Experimenting with RabbitMQ – Topic exchange


Preamble

This is part 4 of a series of blogposts about RabbitMQ. This series aims to provide more information (I cannot vouch for the accuracy of the information as I’m a beginner at RabbitMQ) concerning a series of posts by Derek Greer.

Part 1: Experimenting with RabbitMQ – HelloWorldExample

Part 2: Experimenting with RabbitMQ – LoggingApplication example

Part 3: Experimenting with RabbitMQ – Fanout exchange

Part 4: Experimenting with RabbitMQ – Topic exchange

————————

The code provided here demonstrates a topic exchange and running it works fine (you can get the code here). However, then I tried to filter all the “Business” messages to another consumer and here what I tried first:

using System;
using System.IO;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace Consumer2
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Should show only Business messages");
            Console.WriteLine("==================================");
            const string exchange = "topic-exchange-example";
            const string queue = "log";

            var connectionFactory = new ConnectionFactory();
            var connection = connectionFactory.CreateConnection();
            IModel channel = connection.CreateModel();

            channel.ExchangeDeclare(exchange, ExchangeType.Topic, false, true, null);
            channel.QueueDeclare(queue, false, false, true, null);
            channel.QueueBind(queue, exchange, "*.Business.*");

            var consumer = new QueueingBasicConsumer(channel);
            channel.BasicConsume(queue, true, consumer);

            while (true)
            {
                try
                {
                    var eventArgs = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
                    var message = Encoding.UTF8.GetString(eventArgs.Body);
                    Console.WriteLine(string.Format("{0} - {1}", eventArgs.RoutingKey, message));
                }
                catch (EndOfStreamException)
                {
                    // The consumer was cancelled, the model closed, or the connection went away.
                    break;
                }
            }
            channel.Close();
            connection.Close();
        }
    }
}

This is nearly identical to the Consumer application provided in the original post. When I ran this I got:

Topic

This was definitely not what I was expecting because I would have thought that by specifying

channel.QueueBind(queue, exchange, "*.Business.*");

would have been enough to do the filtering.

Upon further thought, what this is, I believe, saying is bind all the messages that match the routing key “*.Business.*” to the queue “log”. Now, if you consider the same code in “Consumer” itself:

channel.QueueBind(queue, exchange, "*.Personal.*");

So effectively we have bound all messages matching “*.Business.*” and “*.Personal.*” to the same queue “log” and we dequeue it, we’ll get a mixture of both. Hence, the solution to that problem is to create two queues “log-personal” and “log-business” which results in:

Topic correctThis in fact corresponds to this diagram:

Advertisements
Posted in .NET, ALT.NET, RabbitMQ

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

%d bloggers like this: