The NMS API (.Net Message Service API) providers a standard C# interface to Messaging Systems. There could be multiple implementations to different providers (including MSMQ).

NMS API currently supports all of the features of JMS in a simple pure C# API and implementation apart from XA. Current features include

  • creating & disposing of connections, sessions, producers, consumers
  • sending of messages to topics, queues with durable or non durable along with temporary destination support
  • synchronous consuming (blocking receive, receive with no wait or receive with a timeout)
  • asynchronous consuming (adding a MessageListener to be dispatched in the thread pool)
  • JMS message header support along with custom properties
  • Text, Bytes and Map message support
  • support for JMS transactions (sending and acknowledging multiple messages in an atomic transaction)
  • redelivery of messages in rollbacks up to some configured maximum redelivery count

Currently the default provider is based on a pure C# implementation of OpenWire which works with the Apache ActiveMQ broker.

You can browse the source code and tests

Using the right ActiveMQ version

We recommend you use the ActiveMQ 4.1.1 Release or later if you wish to use the OpenWire.Net client.

Example

The following example demonstrates the kinds of things available in OpenWire.Net

IConnectionFactory factory = new ConnectionFactory(new Uri("tcp://localhost:61616"));
using (IConnection connection = factory.CreateConnection())
{
    Console.WriteLine("Created a connection!");
    
    ISession session = connection.CreateSession();
    
    IDestination destination = session.GetQueue("FOO.BAR");
    Console.WriteLine("Using destination: " + destination);
    
    // lets create a consumer and producer
    IMessageConsumer consumer = session.CreateConsumer(destination);
    
    IMessageProducer producer = session.CreateProducer(destination);
    producer.Persistent = true;
    
    // lets send a message
    ITextMessage request = session.CreateTextMessage("Hello World!");
    request.NMSCorrelationID = "abc";
    request.Properties["NMSXGroupID"] = "cheese";
    request.Properties["myHeader"] = "James";
    
    producer.Send(request);
    
    // lets consume a message
    ActiveMQTextMessage message = (ActiveMQTextMessage) consumer.Receive();
    if (message == null)
    {
        Console.WriteLine("No message received!");
    }
    else
    {
        Console.WriteLine("Received message with ID:   " + message.NMSMessageId);
        Console.WriteLine("Received message with text: " + message.Text);
    }
}

Asynchronous consumption

You have the choice of synchronously pulling messages from OpenWire.Net via the Receive*() methods as shown above or you can use the asynchronous approach as the following example

IMessageConsumer consumer = Session.CreateConsumer(Destination);
consumer.Listener += new MessageListener(OnMessage);

The above uses a C# delegate so that the OnMessage() method will be called whenever a message arrives.

Note that the threading contract is similar to that of JMS - messages are dispatched for a single session's consumers in one thread at once. Consumers in different sessions can process messages concurrently but consumers in the same session are guarrenteed to be called by only one thread at once. e.g. if you have 3 consumers on a session then only one of the consumers will be called concurrently.

Building the code

On Windows you can use Visual Studio to build the code. On Linux or OS X you can use Mono.

The build can use Maven or NAnt which both work on .Net and Mono.

For more help see the Building CSharp Code guide.

Alternatives to NMS

We currently have a few alternatives to using NMS and working with ActiveMQ on .Net.

Graphic Design By Hiram