Reliable Messaging with MSMQ and .NET

MSMQ stands for Microsoft Message Queuing is one of the most reliable way to sending and receiving messages from one system to another system; both system can be located at different geographical locations. The benefit of MSMQ is that the receiving application doesn’t have to run at the time of sending the message. Messages are stored in the queue of the system (Microsoft Operating System) and once the receiving application runs, it starts peeking the messages one by one.

To perform a task asynchronously is to execute it without waiting for a result. This type of processing allows we to start a time-consuming process and continue working without having to wait for that process to finish executing.
Asynchronous processing is ideal to use in many situations—especially on the Web, where a user’s request could take a long time to process, but we want to provide a response back to the user immediately. By handling the user’s request asynchronously, our system can respond regardless of how long that request may actually take to execute.

To install Message Queuing 4.0 on Windows Server 2008 or Windows Server 2008 R2

In Server Manager, click Features.
In the right-hand pane under Features Summary, click Add Features.
In the resulting window, expand Message Queuing.
Expand Message Queuing Services.
Click Directory Services Integration (for computers joined to a Domain), then click HTTP Support.
Click Next, then click Install.

To install Message Queuing 4.0 on Windows 7 or Windows Vista

Open Control Panel.
Click Programs and then, under Programs and Features, click Turn Windows Features on and off.
Expand Microsoft Message Queue (MSMQ) Server, expand Microsoft Message Queue (MSMQ) Server Core, and then select the check boxes for the following Message Queuing features to install:
MSMQ Active Directory Domain Services Integration (for computers joined to a Domain).
MSMQ HTTP Support.
Click OK.
If we are prompted to restart the computer, click OK to complete the installation.

To install Message Queuing 3.0 on Windows XP and Windows Server 2003

Open Control Panel.
Click Add Remove Programs and then click Add Windows Components.
Select Message Queuing and click Details.
System_CAPS_noteNote
If we are running Windows Server 2003, select Application Server to access Message Queuing.
Ensure that the option MSMQ HTTP Support is selected on the details page.
Click OK to exit the details page, and then click Next. Complete the installation.
If we are prompted to restart the computer, click OK to complete the installation.

To Check MSMQ interface:
My Computer -> Manage -> Services and Applications -> Message Queueing.

There are two types of Messaging Queue:
1. Public Queue:
Provide Message routing.
Public queues are accessed through “Machine nameQueue name”
2. Private Queue:
Do not Provide any routing.
Private queues are accessed through “Machine namePrivate$Queue name”.
If MSMQ is installed on the same machine as our application then we can replace the machine name with a dot, for example “.Private$testQue”

Creating a Queue in the system
Creating a queue in the system is an easy task. Go to My Computer and right click, select Manage and explore the nodes as displayed in the picture below.
IC163748
Right click the Private Queues and select New > Priovate Queue and create a queue. Alternatively, this can be done using C# code as well. My code snippet below does that automatically (ie. if queue doesn’t exists, it creates otherwise use the existing one).

Creating Queues Programmatically
Although the MSMQ interface is available for creating, deleting, and exploring message queues, we can also work with queues through the System.Messaging namespace. Several static methods (meaning we can call them without creating an actual instance of the class) have been provided on the MessageQueue class that give we the ability to check if a queue exists (Exists), create a queue (Create), and delete a queue (Delete). Using these methods, our application can check for the existence of a queue, and create it automatically if it does not exist. The function, GetQ, listed next provides the exact functionality just described:

 if (MessageQueue.Exists(@".\Private$\MyQueue"))
 {
     myQueue = new MessageQueue(@".\Private$\MyQueue");
 }
 else
 {
     myQueue = MessageQueue.Create(@".\Private$\MyQueue");
 }
Delete
 MessageQueue.Delete(@".\Private$\MyQueue")

Now, let’s send a message to the MSMQ
The following code example shows how to  send a message, setting a few options including formatting and encryption before using the MessageQueue object’s Send method with the preconfigured Message object:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace MessageSender
{
    class Program
    {
        static void Main(string[] args)
        {
            do
            {
                Console.WriteLine("Enter Message to be send");
                Console.WriteLine("High Priority Message should be start with HP:");
                string text = Console.ReadLine();

                MessageQueue myQueue;

                if (MessageQueue.Exists(@".\Private$\MyQueue"))
                {
                    myQueue = new MessageQueue(@".\Private$\MyQueue");
                }
                else
                {
                    myQueue = MessageQueue.Create(@".\Private$\MyQueue");
                }
                Message message = new System.Messaging.Message();
                message.Formatter = new BinaryMessageFormatter();
                message.Body = text;
                message.Label = "myTestMessage";

                if (text.Contains("HP:")) { message.Priority = MessagePriority.High; }
                else { message.Priority = MessagePriority.Normal; }
                myQueue.Send(message);
                Console.WriteLine("Message has sent");
            } while (Console.ReadKey().Key != ConsoleKey.Q);
        }
    }
}

One of the key message options we may wish to specify controls how the message is serialized for sending. By default, this is set to use XMLMessageFormatter, which serializes objects into an XML representation and is suitable for most purposes. Two other formatters are available, however: the BinaryMessageFormatter and ActiveXMessageFormatter, both of which serialize objects into a binary (not human-readable like XML) format.

Receiving messages from MSMQ
To receive a message from queue, we need to first instantiate the queue using MessageQueue. we will need to make sure that the queue exists, otherwise we shall get an error.
Once we have placed messages onto our queue, someone will likely wish to retrieve those messages, taking the data off the queue in the order in which it was added. To obtain a message from the queue, and then retrieve the data it contains, requires a few important steps:

* First, as with sending a message, obtain a MessageQueue object pointing at the       appropriate queue:
var myQueue = new MessageQueue(@”.\Private$\MyQueue”);
* Next, use the Receive method of the queue to obtain the first message from the queue:
Message message = myQueue.Receive();
* Then, if we are using the XML formatter (the default), set up the formatter of the Message object with a list of possible data types that might be contained in the message. In this case, we are expecting only one possible data type, String:
Message message = myQueue.Receive();
message.Formatter = new BinaryMessageFormatter();
* Finally, use the Body property to retrieve our data, casting it into the appropriate type:
Console.WriteLine(message.Body.ToString())

With large messages and slow network links in mind, the MessageQueue object provides an asynchronous way to receive messages in addition to the Receive method. To receive a message asynchronously, we proceed as before and obtain a reference to the appropriate queue, and then, instead of calling Receive, we will call BeginReceive (specifying a time-out if desired). This starts the receive process, and execution will continue immediately with the next line of code.
When a message has been successfully retrieved,and the MessageQueue object’s ReceiveCompleted event will fire and our event handler will be called. The retrieved message is sent to our event handler as part of one of its parameters, and we can use that object to retrieve the actual data as usual.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace MessageReceiver
{
    class Program
    {
        private static MessageQueue myQueue = null;
        private static object lockObject = new object();

        static void Main(string[] args)
        {
            Console.WriteLine("Received Messages");

            myQueue = new MessageQueue(@".\Private$\MyQueue");
            // Setup an event to listen for new messages.
            myQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(queue_ReceiveCompleted);

            // Start listening.
            myQueue.BeginReceive();
            /*Message message = myQueue.Receive();
            message.Formatter = new BinaryMessageFormatter();
            Console.WriteLine(message.Body.ToString());*/
            while (Console.ReadKey().Key != ConsoleKey.Q)
            {
                // Press q to exit.
            }
        }


        static void queue_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
        {
            lock (lockObject)
            {
                // The message is plain text.
                e.Message.Formatter = new BinaryMessageFormatter();
                string text = (string)e.Message.Body;
                Console.WriteLine("Message received: " + text);
            }

            // Listen for the next message.
            myQueue.BeginReceive();
        }
    }
}

tutorial: https://www.youtube.com/watch?v=ZHiu81Gqb_o

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s