RabbitMQ in ASP.NET Core

RabbitMQ is a message broker, a service responsible for exchanging messages between different software services.

RabbitMQ keeps messages in a queue (Queue), which is a named buffer that stores messages addressed to it.

The program that sends messages to the RabbitMQ queue is called a Producer.

The program that receives the messages is called the Subscriber. Such programs subscribe to events when a message enters the queue, and are always waiting for new messages.

Multiple providers may send messages to the queue, and multiple subscribers may read messages from the queue.

  1. Starting the RabbitMQ Server

For the purposes of this tutorial, we need to have a RabbitMQ service running, and we can do this in two ways: deploy a RabbitMQ server locally in a docker container, or use a third-party cloud service. Below we will consider both options, and you can choose the most suitable for yourself.

1.1. Method 1: Run the RabbitMQ server in a docker container on your local machine

To do this, we need to have the Docker Desktop software installed on our computer beforehand.

– To do this, follow the link https://www.docker.com/products/docker-desktopdownload the installer and run it.

It is important to choose options Enable Hyper-V Windows Features or Install required Windows components for WSL 2, when the installer asks for it.

Follow the instructions of the installer, and at the end of the installation process, click the button close.

We find Docker Desktop in the list of programs installed on the computer, and launch it.

In the Windows command line or in PowerShell, run the following two commands in turn:

docker run -d --hostname my-rabbit-host --name my-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password rabbitmq:3-management

and

docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management

Do not close the command line window.

In the Docker Desktop application, on the tab Containers/Apps we will see running RabbitMQ containers:

In the browser, go to the link localhost:15672. Enter guest and guest in the username and password fields. This is where we can manage our RabbitMQ service.

1.2. Method 2: Registration in the cloud service CloudAMQP and configuring the RabbitMQ service

We go to the address https://www.cloudamqp.com/plans.html.

Choose a free plan Little Lemur (click Get Now).

We register on the site.

We create a new entity (instance) RabbitMQ.

On the next page, select the available server location region and click Review.

On the Configure page, click create instance.

On the next page, click on the name of our new entity:

and get into the control panel of our RabbitMQ instance:

  1. Using RabbitMQ in ASP.NET Core Projects

Let’s create 2 ASP.NET Core Web API projects: a project that will be a message provider (producer) and a project that will be a subscriber (consumer).

For both projects, after creating them in the following steps, you need to install the NuGet package: RabbitMQ.Client.

To do this, in SolutionExplorer (Solution Explorer), right-click on the name of the working project and select Manage NuGet Packages… (Managing Nuget Packages).

Next, go to the leftmost tab Browse, and in the search bar enter the name of the NuGet package to be installed.

In the left window, select the package we need, and in the right, click the button Install.

2.1. Create an ASP.NET Core Web API project with a producer.

Create a new project in Visual Studio ASP.NET CoreWeb API:

Add the RabbitMQ.Client NuGet package to the new project as described above.

In the root of the project, create a folder “RabbitMq”, and in this folder we create an interface:

public interface IRabbitMqService
{
	void SendMessage(string message);
}

In the same folder, create a class:

using RabbitMQ.Client;
using System.Text;

public class RabbitMqService : IRabbitMqService
{
	public void SendMessage(string message)
	{
		var factory = new ConnectionFactory() { HostName = "localhost" };
		using (var connection = factory.CreateConnection())
		using (var channel = connection.CreateModel())
		{
			channel.QueueDeclare(queue: "MyQueue",
                           durable: false,
                           exclusive: false,
                           autoDelete: false,
                           arguments: null);

			var body = Encoding.UTF8.GetBytes(message);

			channel.BasicPublish(exchange: "",
                           routingKey: "MyQueue",
                           basicProperties: null,
                           body: body);
		}
	}
}

In this example, we have created a producer for the local RabbitMQ server:

var factory = new ConnectionFactory() { HostName = "localhost" };

For the RabbitMQ cloud service, you need to change this line.

Let’s go to the CloudAMQP control panel, and click the “copy” icon next to the connection string: AMQP URL.

Let’s paste the copied connection string into our code:

var factory = new ConnectionFactory() { Uri = new Uri("строка_подключения") };

Now the producer will send messages to the cloud service.

Let’s add the RabbitMqService class to the DI container. To do this, add the following line to the ConfigureServices method of the Startup class:

public void ConfigureServices(IServiceCollection services)
{
	// другой код
	services.AddScoped<IRabbitMqService, RabbitMqService>();
	// другой код
}

Add a new API controller to the Controllers folder:

Let’s add code to it:

using Microsoft.AspNetCore.Mvc;
using RabbitMqProducer.RabbitMq;

[Route("api/[controller]")]
[ApiController]
public class RabbitMqController : ControllerBase
{
	private readonly IRabbitMqService _mqService;

	public RabbitMqController(IRabbitMqService mqService)
	{
		_mqService = mqService;
	}

	[Route("[action]/{message}")]
	[HttpGet]
	public IActionResult SendMessage(string message)
	{
		_mqService.SendMessage(message);

		return Ok("Сообщение отправлено");
	}
}

Let’s start the project, and in swagger (https://localhost:your_port/swagger/index.html) call the SendMessage method, passing an arbitrary string as a parameter. To do this, click on the line of this method, in the panel that opens at the top right, click the button Try it out and in the window message Let’s enter our message. Let’s press the button Execute.

In response, we should receive the status code 200 and the message “Message sent”.

If you are using a local RabbitMQ server, go to the control panel of the local RabbitMQ instance (http://localhost:15672).

If you use the CloudAMQP cloud service, go to its control panel. Click the button at the top of the left menu RabbitMQ Manager and get into the same RabbitMQ control panel as for the local instance.

Let’s go to the Queues tab, in the table, click on the name of our queue (“MyQueue”).

Expand the element in the list below get messages, press the button Get message(s), and see our message “Hello Rabbit!”:

The producer is working.

2.2. Create an ASP.NET Core Web API project with a consumer.

Create a new ASP.NET Core Web API project in Visual Studio.

Add the RabbitMQ.Client NuGet package to the new project as described above.

Create a folder “RabbitMq” in the root of the project, and create a class in this folder:

using RabbitMQ.Client.Events;
using RabbitMQ.Client;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.Extensions.Hosting;
using System.Text;
using System.Diagnostics;


public class RabbitMqListener : BackgroundService
{        
	private readonly IModel _channel;

	public RabbitMqListener()
	{		
		var factory = new ConnectionFactory { HostName = "localhost" };
		var connection = factory.CreateConnection();
		_channel = connection.CreateModel();
		_channel.QueueDeclare(queue: "MyQueue", durable: false, exclusive: false, autoDelete: false, arguments: null);
	}

	protected override Task ExecuteAsync(CancellationToken stoppingToken)
	{
		stoppingToken.ThrowIfCancellationRequested();

		var consumer = new EventingBasicConsumer(_channel);
		consumer.Received += (ch, ea) =>
		{
			var content = Encoding.UTF8.GetString(ea.Body.ToArray());

			Debug.WriteLine($"Получено сообщение: {content}");

			_channel.BasicAck(ea.DeliveryTag, false);
		};

		_channel.BasicConsume("MyQueue", false, consumer);

		return Task.CompletedTask;
	}
}

In this example, we have created a consumer for the local RabbitMQ server:

var factory = new ConnectionFactory() { HostName = "localhost" };

For the RabbitMQ cloud service, you need to change this line as described above in the section on creating a producer.

Add the following line to the ConfigureServices method of the Startup class:

services.AddHostedService<RabbitMqListener>();

We will launch both projects – a producer and a consumer.

Let’s go to the producer’s swagger and send a custom message.

In the Output from Debug window, our message will appear, displayed by the method

Debug.WriteLine($"Получено сообщение: {content}");

our consumer.

2.3. Create a .NET Core Console App project with a consumer.

To do this, add the following code to the Main method of the Program class of the new project:

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

static void Main(string[] args)
{
	var factory = new ConnectionFactory() { HostName = "localhost" };
  //var factory = new ConnectionFactory() { Uri = new Uri("строка_подключения_облако") };
	using (var connection = factory.CreateConnection())
	using (var channel = connection.CreateModel())
	{
		channel.QueueDeclare(queue: "MyQueue",
							 durable: false,
							 exclusive: false,
							 autoDelete: false,
							 arguments: null);

		var consumer = new EventingBasicConsumer(channel);
		consumer.Received += (model, ea) =>
		{
			var body = ea.Body.ToArray();
			var message = Encoding.UTF8.GetString(body);
			Console.WriteLine(" [x] Received {0}", message);
		};
		channel.BasicConsume(queue: "MyQueue",
							 autoAck: true,
							 consumer: consumer);

		Console.WriteLine(" Press [enter] to exit.");
		Console.ReadLine();
	}
}

And we start the project. The received message will be output to the console.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *