Click here to Skip to main content
15,885,032 members
Articles / All Topics

Implementing pub-sub using MSMQ in 15 minutes

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
1 Feb 2015CPOL2 min read 26.2K   8   2
Requirements: 1. Install MSMQ. By default the service is not enabled. To do this on Windows 7: a. Launch Control Panel an click on Turn Windows features on or off. b. Select Microsoft Message Queue (MSMQ) Server. c. Under this option, select MSMQ HTTP Support and Multicasting Support.

Requirements:

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

a. Launch Control Panel an click on 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 privat 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. Contrast this with RabbitMQ where messages are distributed between subscribers, although I would suspect that our quick 15 minute tutorial on RabbitMQ probably is missing a setting to allow equal distribution of messages among the subscribers.


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questiongot an exception Pin
Michael Chao11-May-17 8:19
Michael Chao11-May-17 8:19 
QuestionThis does not work in different machine. Multicast should work in different server? Pin
Rajeshmishra9014-Jun-16 1:36
Rajeshmishra9014-Jun-16 1:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.