Implementing RabbitMQ🐰, For Point to Point Communication 🚀

In this tutorial, we are going to discuss RabbitMQ, a very popular and user-friendly Message Broker. To get started, let us understand what Message Broker is.

What is a Message Broker?

A message broker is an architectural pattern for message validation, transformation, and routing. It mediates the communication among applications. They are inter-application communication technologies. They help us in building common integration mechanisms for Microservices and other distributed-based architectures. The applications built on different languages can also communicate with each other through this. They rely on message queues. The message is consumed in the order they are produced. This message queue is just like a traditional queue data structure. It is based on First In First Out Basis.

The message brokers offer two message distribution styles.

  1. Point-To-Point
  2. Publisher/Subscriber

Examples of message brokers are.

  1. RabbitMQ
  2. Apache Kafka
  3. ActiveMQ
  4. KubeMQ
  5. Amazon MQ
  6. Azure Service Bus

What is RabbitMQ?

RabbitMQ is an open-source message broker. It is lightweight and can be easily deployed to on-premise or cloud. It can run on many operating systems and provides a wide range of developer tools for many languages. Some features of RabbitMQ are:

  1. Asynchronous Messaging
  2. Distributed Deployment
  3. Management and Monitoring
  4. Extensible through Plugins and Tools

What will be covered in this Tutorial?

In this tutorial, we are going to implement Point-To-Point communication. In this one message will be sent from the Producer to the Consumer. We will write 2 methods that can be used in C#. How to Invoke the functions through UI is entirely the choice of the developer. Once invoked, we will then monitor their execution flows.

Pre-Requisites

  1. The RabbitMQ server is up and running locally or cloud. For local setup details, check here.
  2. Visual Studio 2019, For details, check here.
  3. Some Exposure to ASP.NET Core.
  4. Some Exposure to RabbitMQ.
    • Install Nuget Package: RabbitMQ.Clients
    • Package Manager: Install-Package RabbitMQ.Client
    • .NET CLI: dotnet add package RabbitMQ.Client
    • Package Reference: <PackageReference Include="RabbitMQ.Client" Version="6.1.0" />

Now, let us look at the source code for Producer and Consumer, we will create 2 functions.

Configuration in appsettings.json

{
  "Rabbit-MQ-AMPQ": "amqp://[username]:[password]-@[server]/[path]"
}

Producer, In Application 1

using RabbitMQ.Models;
using RabbitMQ.Client;
using Microsoft.Extensions.Configuration;
using System.Text;

public void Produce(string message)
{
    var factory = new ConnectionFactory()
    {
        Uri = new Uri(configuration["Rabbit-MQ-AMPQ"]) // Through DI
    };

    using (var conn = factory.CreateConnection())
    {
        using (var channel = conn.CreateModel())
        {
            channel.QueueDeclare(queue: "messages_share",
                                 durable: false,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null);

            var body = Encoding.UTF8.GetBytes(message);
            channel.BasicPublish(exchange: "",
                                 routingKey: "messages_share",
                                 basicProperties: null,
                                 body: body);

            Console.WriteLine("[x] Sent {0}", message);
        }
    }
}

Explanation of Producer Code

Create a connection, open a channel, and create the queue. Send the message to the queue. After completion of the task, auto-dispose of the connections.

Consumer, In Application 2

/* 
using Microsoft.Extensions.Configuration;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
*/
   
public void Consume()
{
    var factory = new ConnectionFactory()
    {
        Uri = new Uri(configuration["Rabbit-MQ-AMPQ"]) //Through DI
    };

    var conn = factory.CreateConnection();

    var channel = conn.CreateModel();

    channel.QueueDeclare(queue: "messages_share",
                         durable: false,
                         exclusive: false,
                         autoDelete: false,
                         arguments: null);

    var consumer = new EventingBasicConsumer(channel);

    consumer.Received += (ch, ea) =>
    {
        var body = Encoding.UTF8.GetString(ea.Body.ToArray());
        Console.WriteLine(body + "\n");
        channel.BasicAck(ea.DeliveryTag, false);
    };

    channel.BasicConsume("messages_share", false, consumer);
}

Explanation of Consumer Code

Connect to the channel, and declare the queue (this helps us to ensure that the queue exists). Subscribe to the channel. When a message is received, then perform logic on that message. Do not close the connection, as the channel is open for messages to arrive.

Execution Flow

  1. Call the Consumer function once, only at the startup of the application to open the communication channel. The channel will be visible in the RabbitMQ Channels Admin UI.
    RabbitMQ Channel
  2. Now send the execution call from the producer function.
  3. The consumer will automatically catch this as the channel is open.
  4. Monitor the activity in the Queues Section of RabbitMQ.

Overall communication will look like this, the image should be self-explanatory.

Self-explanatory

This image shows that the message “Hello There” was fired from Application 1. This message went to the RabbitMQ server. The Application 2 had subscribed through a Received event. The message was forwarded from RabbitMQ to Application 2 as part of the subscription. This Application 2 Channel was open so it was able to receive the message at the same time.

Summary

We covered Message Broker, About RabbitMQ, and Implement RabbitMQ in .NET for Point-to-Point Communication.

Please feel free to share your thoughts, and comments and share your knowledge for improvement.


Similar Articles