Implementing pub-sub using MSMQ in 15 minutes

Requirements:

1. Install MSMQ. By default the service is not enabled. To do this on Windows 7:

a. Launch the Control Panel and click on Programs | Turn Windows features on or off.
b. Select Microsoft Message Queue (MSMQ) Server.
c. Under this option, select MSMQ HTTP Support and Multicasting Support.
HTTP Support provides the ability to send messages across the internet.
Multicasting provides the ability for publish subscribe.

2. Click OK.
3. Open Computer Manager to confirm that you have a new listing under Services and Applications called Message Queuing with Outgoing, Private and System Queue folders.

Implementing Pub/Sub using MSMQ
1. Create a new C# Console Project.
2. Add reference to System.Messaging dll.
3. Modify Program.cs to look like follows:

    class Publisher
    {
        static void Main(string[] args)
        {
            //1. establish the queue
            using (var helloQueue = new MessageQueue("FormatName:MULTICAST=234.1.1.1:8001"))
            {
                while (true)
                {
                    var stopWatch = new Stopwatch();
                    stopWatch.Start();

                    //2. create a message, that can be anything since it is a byte array
                    for (var i = 0; i < 1000; i++)
                    {
                        SendMessage(helloQueue,
                            string.Format("{0}: msg:{1} hello world ", DateTime.UtcNow.Ticks, i));
                        Thread.Sleep(10);
                    }

                    stopWatch.Stop();
                    Console.ReadLine();

                    Console.WriteLine("====================================================");
                    Console.WriteLine("[MSMQ] done sending 1000 messages in " + stopWatch.ElapsedMilliseconds);
                    Console.WriteLine("[MSMQ] Sending reset counter to consumers.");

                    SendMessage(helloQueue, "reset");
                    Console.ReadLine();
                }
            }

        }

        private static void SendMessage(MessageQueue queue, string content)
        {
            //3. send the message
            queue.Send(content);
            Console.WriteLine(" [MSMQ] Sent {0}", content);
        }
    }

4. Create a new C# console project and add a reference to the System.Messaging dll.
5. Modify Program.cs to look like this:

  class Subscriber
    {
        static void Main(string[] args)
        {
            int messagesReceived = 0;
            var messages = new Queue<string>(5000);
            var filePath = typeof (Subscriber).FullName + ".txt";
            var path = @".\private$\hello-queue";

            using (var helloQueue = new MessageQueue(path))
            {
                helloQueue.MulticastAddress = "234.1.1.1:8001";
                while (true)
                {
                    var message = helloQueue.Receive();
                    if (message == null)
                        return;

                    var reader = new StreamReader(message.BodyStream);
                    var body = reader.ReadToEnd();

                    messagesReceived += 1;

                    messages.Enqueue(body);
                    Console.WriteLine(" [MSMQ] {0} Received {1}", messagesReceived, body);

                    if (string.CompareOrdinal("reset", body) == 0)
                    {
                        messagesReceived = 0;
                        File.WriteAllText(filePath, body);
                        messages.Clear();
                    }
                }
            }
        }
    }

Some implementation notes

1. Publish/subscribe requires a different queue path format. For fire and forget, the queue format is .\private$\hello-queue if sending to a private queue. For pub/sub, we need a multicast address in the form FormatName:MULTICAST=234.1.1.1:8001.
2. Messages received are not exactly same as sent. By default MSMQ uses an XML serializer so our plain string is now wrapped in an XML tag.
3. A multicast subscriber queue is just a regular queue with a multicast address. So you can create many different queues with different names with the same multicast address to receive the same message from the publisher.
4. You can have many publishers and many subscribers. All the subscribers receive all of the messages from each publisher.

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