RabbitMQ Headers Exchange in C# to Publish or Consume Messages

In rabbitmq, Headers Exchange will use the message header attributes to send a messages to queue instead of routing key.

 

The headers exchange is useful when we want to route a messages based on header values instead of routing keys.

 

Generally, in rabbitmq when producer creates a message that will not directly send to queue, instead first the message will be send to exchanges, then after that a routing agent reads and sends it to the appropriate queue with help of header attributes, bindings and routing keys.

 

In rabbitmq, we have a different type of exchanges available those are

 

  • Direct
  • Fanout
  • Topic
  • Headers

To know more about exchanges in rabbitmq, check this RabbitMQ Exchanges.

 

Following is the pictorial representation of message flow in rabbit headers exchange.

 

RabbitMQ Headers Exchange Process Flow Diagram

 

Now, we will learn how to use headers Exchange to push and read messages from rabbitmq in c# or .net application with examples.

C# Create RequestRabbitMQ Application

Let’s create a simple console application with Name “RequestRabbitMQ” like as shown below to publish a messages to rabbitmq queue using headers exchange in c#.

 

C# Create Application to Publish Messages to RabbitMQ

 

After creating an application, now we will add “RabbitMQ.Client” nuget package in our c# application to communicate with rabbitmq server to publish or consume messages from queues in rabbitmq.

Add RabbitMQ.Client NuGet Package

In c#, we can publish or consume messages from rabbitmq by using RabbitMQ.Client nuget package for that, right click on your application and select Manage NuGet Packages like as shown below.

 

C# Add RabbitMQ.Client Nuget Package Reference to Application

 

Now search for RabbitMQ.Client package and install it in your application like as shown below.

 

C# Adding RabbitMQ.Client NuGet Package Reference

 

Following is the another way to install RabbitMQ.Client package by using Package Manager Console like as shown below by entering following command.

 

Command to install - Install-Package RabbitMQ.Client -Version 5.1.0 

 

C# Add RabbitMQ.Client Nuget Package Reference from Package Manager Console

 

Before we start write a code in c# to publish a messages to rabbitmq, we will create a headers exchange, queue and will bind a queue to exchange using web admin console.

RabbitMQ Create Headers Exchange

To create an exchange in rabbitmq web management portal, open http://localhost:15672/#/exchanges url and then go to Add a new exchange panel and enter a details like as shown below by selecting Type as “headers” and click on Add exchange button to create an exchange (headers.exchange).

 

Create Headers Exchange in RabbitMQ Web Management Portal

 

After creating an exchange (headers.exchange), next we will create two queues (ReportPDF, ReportExcel) in web management portal.

RabbitMQ Create a Queue

To create a queue in rabbitmq web management portal, open http://localhost:15672/#/queues url and then go to Add a new queue panel and enter a details like as shown below and click on Add queue button to create a queue (ReportPDF).

 

Create a Queue in RabbitMQ Web Management Portal

 

Similar way, create another queue (ReportExcel) and following is the list of queues which we created in rabbitmq web management portal.

 

RabbitMQ Headers Exchange Queues List

 

After creating a queue and exchange, next we need to bind a queue with exchange in rabbitmq web admin console.

RabbitMQ Bind Queue to Exchange

To bind a queue with exchange, click on queue (ReportPDF) name, then the Bindings panel will expand and enter a details like exchange name as “headers.exchange”, Argument details and click on Bind button.

 

RabbitMQ Bind Queue to Headers Exchange

 

If you observe above diagram, we entered a required arguments (format, x-match) to route a messages based on header values instead of routing keys.

 

Here, for x-match attribute we can set two values either all or any based on our requirements but all is the default value for headers binding.

 

AttributeDescription
x-match = all It means all the header values must match.
x-match = any It means just one matching header value is sufficient.

After binding a queue (ReportPDF) to exchange (headers.exchange), the binding will be like as shown below. 

 

RabbitMQ Bind Queue to Headers Exchange

 

Same way we will bind a ReportExcel queue to headers.exchange like as shown below by entering exchange name and argument values based on our requirements.

 

RabbitMQ Bind Headers Exchange to Queue

 

After binding a queue (ReportExcel) to exchange (headers.exchange), the binding will be like as shown below.

 

RabbitMQ Queue Binding Details

 

After completion of binding a queues to exchange, now we will publish a messages from c# application to rabbitmq queue using RabbitMQ.Client service.

C# Publish Messages to RabbitMQ

To publish a messages to rabbitmq queue, add a class with name “Headersmessages.cs” in your application like as shown below.

 

C# Add Class to Publish Messages to RabbitMQ using Headers Exchange

 

Now, open Headersmessages.cs class file and write the code like as shown below.

Headersmessages.cs

using RabbitMQ.Client;

using System;

using System.Collections.Generic;

using System.Text;

 

namespace RequestRabbitMQ

{

    public class Headersmessages

    {

        private const string UName = "guest";

        private const string PWD = "guest";

        private const string HName = "localhost";

        public void SendMessage()

        {

            //Main entry point to the RabbitMQ .NET AMQP client

            var connectionFactory = new ConnectionFactory()

            {

                UserName = UName,

                Password = PWD,

                HostName = HName

            };

            var connection = connectionFactory.CreateConnection();

            var model = connection.CreateModel();

            var properties = model.CreateBasicProperties();

            properties.Persistent = false;

            Dictionary<string, object> dictionary = new Dictionary<string, object>();

            dictionary.Add("format", "pdf");

            properties.Headers = dictionary;

            byte[] messagebuffer = Encoding.Default.GetBytes("Message to Headers Exchange 'format=pdf' ");

            model.BasicPublish("headers.exchange", "", properties, messagebuffer);

            Console.WriteLine("Message Sent From : headers.exchange ");

            Console.WriteLine("Routing Key : Does not need routing key");

            Console.WriteLine("Message Sent");

        }

    }

}

If you observe above code, to establish a connection with rabbitmq server we are passing a required credentials along with HostName to ConnectionFactory() method. After that, we are publishing a message (Message to Headers Exchange 'format=pdf') to queue by passing required parameters like exchange, routing key, properties and message to BasicPublish method.

 

Now open Program.cs class file and write a code in Main method to call Headersmessages.cs class to get a messages from rabbitmq.

Program.cs

Following is the code which we need to write in Program.cs class file Main method to publish a messages to rabbitmq server.

 

using System;

namespace RequestRabbitMQ

{

    class Program

    {

        static void Main(string[] args)

        {

            Headersmessages headersmessages = new Headersmessages();

            headersmessages.SendMessage();

            Console.ReadLine();

        }

    }

}

When we execute above c# program, we will get the result like as shown below.

 

C# Publish Message RabbitMQ Queue using Headers Exchange Example Result

 

After executing above program, if we check the queue (ReportPDF) details in rabbitmq web management portal, the Ready column is having 1 like as shown below that means message published successfully to ReportPDF queue.

 

RabbitMQ After Publishing Message to Queue

 

After publishing a message to queue, now will learn how to consume or get a messages from rabbitmq using RabbitMQ.Client service in c# or .net application with examples.

C# Create RabbitMQConsumer Application

Let’s create simple console application with Name “RabbitMQConsumer” like as shown below to consume or read a messages from rabbitmq queue.

 

C# Console Application to Read or Consume Messages from RabbitMQ

 

After creating an application, now add “RabbitMQ.Client” nuget package reference to your application like as we did in publishing application to communicate with rabbitmq server.

C# Consume Messages from RabbitMQ

After installing RabbitMQ.Client, next add a class with name “MessageReceiver.cs” in your application like as shown below to read or get a messages from queues in rabbitmq.

 

C# Console Application Add New Class File to Read Messages from RabbitMQ

 

Now, open MessageReceiver.cs class file and write the code like as shown below.

MessageReceiver.cs

using System;

using System.Text;

using RabbitMQ.Client;

 

namespace RabbitMQConsumer

{

    public class MessageReceiver : DefaultBasicConsumer

    {

        private readonly IModel _channel;

        public MessageReceiver(IModel channel)

        {

            _channel = channel;

        } 

        public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, byte[] body)

        {

            Console.WriteLine($"Consuming Headers Message");

            Console.WriteLine(string.Concat("Message received from the exchange ", exchange));

            Console.WriteLine(string.Concat("Consumer tag: ", consumerTag));

            Console.WriteLine(string.Concat("Delivery tag: ", deliveryTag));

            Console.WriteLine(string.Concat("Routing tag: ", routingKey));

            Console.WriteLine(string.Concat("Message: "Encoding.UTF8.GetString(body)));

            _channel.BasicAck(deliveryTag, false);

        }

    }

}

If you observe above code, we created a MessageReceiver class and it’s inheriting from DefaultBasicConsumer class of RabbitMQ.Client service and we implemented a HandleBasicDeliver method by overriding it to receive a message body.

 

Now open Program.cs class file and write a code in Main method to call MessageReceiver.cs class to get a messages from rabbitmq.

Program.cs

Following is the code which we need to write in Program.cs class file Main method to receive a data from rabbitmq server.

 

using System;

using RabbitMQ.Client;

 

namespace RabbitMQConsumer

{

    class Program

    {

        private const string UName = "guest";

        private const string Pwd = "guest";

        private const string HName = "localhost";

 

        static void Main(string[] args)

        {

            ConnectionFactory connectionFactory = new ConnectionFactory

            {

                HostName = HName,

                UserName = UName,

                Password = Pwd,

            };

            var connection = connectionFactory.CreateConnection();

            var channel = connection.CreateModel();

            // accept only one unack-ed message at a time

            // uint prefetchSize, ushort prefetchCount, bool global

            channel.BasicQos(0, 1, false);

            MessageReceiver messageReceiver = new MessageReceiver(channel);

            channel.BasicConsume("ReportPDF"false, messageReceiver);

            Console.ReadLine();

        }

    }

}

If you observe above example, to establish a connection with rabbitmq server we are passing a required credentials along with HostName to ConnectionFactory() method. After that, we created a connection and channel by calling “CreateConnection” and “CreateModel” methods and we set a prefetchCount to 1, so that it tells RabbitMQ not to give more than one message at a time to worker.

 

Next, we have created an instance of MessageReceiver class and passed IModel (channel) to it, in final step we have called “BasicConsume” method and passed queue name to it “ReportPDF” along with we have set autoAck to false and passed the messageReceiver instance to it. 

 

Here, prefetchCount is used to tell RabbitMQ not to give more than one message at a time to worker. Or, in other words, don't dispatch a new message to a worker until it has processed and acknowledged the previous one. Instead, it will dispatch to the next worker that is not still busy. 

 

When we execute our application, we will get a messages from queue (ReportPDF) like as shown below.

 

C# Consume Messages from RabbitMQ using Headers Exchange Example Result

 

This is how we can rabbitmq headers exchanges to consume or read a messages from queues in c# using RabbitMQ.Client service based on our requirements.