Enviando mensagens com RabbitMQ

Concluído

É simples escrever código que cria filas, envia mensagens e recebe mensagens do RabbitMQ. Em uma solução .NET Aspir, você também tem ajuda para criar o contêiner RabbitMQ e fazer conexões com ele a partir de microsserviços.

Em seu varejista de equipamentos para atividades ao ar livre, você decidiu implementar o RabbitMQ como um agente de mensagens centralizado para seu site de catálogo de produtos voltado para o cliente. Você deseja usar a integração do .NET Aspire RabbitMQ para gerenciar esse broker e suas filas.

Nesta unidade, você aprenderá como criar um contêiner RabbitMQ e usá-lo para enviar e receber mensagens.

Usando a integração .NET Aspire RabbitMQ

Quando você usa o RabbitMQ do .NET, geralmente precisa criar um ConnectionFactory objeto com uma cadeia de conexão e, em seguida, usá-lo para fazer conexões com o serviço. Em um projeto .NET Aspire é mais fácil gerenciar a conexão RabbitMQ porque:

  • Você registra uma conexão e uma cadeia de conexão no projeto AppHost .
  • Quando você passa uma referência ao serviço para projetos de consumo, eles podem usar a injeção de dependência para obter uma conexão com o RabbitMQ. Eles não precisam criar e configurar suas próprias conexões.

Configurando o RabbitMQ no host do aplicativo

No .NET Aspire, você deve instalar a integração de hospedagem MQ do Rabbit no host do aplicativo:

dotnet add package Aspire.Hosting.RabbitMQ

Agora, você pode registrar o serviço RabbitMQ e passá-lo para projetos que o usam:

// Service registration
var rabbit = builder.AddRabbitMQ("messaging");

// Service consumption
builder.AddProject<Projects.CatalogAPI>()
       .WithReference(rabbit);

O AppHost gerencia a conexão para todos os projetos na solução.

Configurando o Rab

Em seguida, adicione a integração do .NET Aspire RabbitMQ a cada projeto que o utiliza:

dotnet add package Aspire.RabbitMQ.Client

Para obter uma referência ao agente de mensagens RabbitMQ, chame o AddRabbitMQClient() método:

builder.AddRabbitMQClient("messaging");

Agora, você pode usar a injeção de dependência para obter a conexão com o RabbitMQ:

public class CatalogAPI(IConnection rabbitConnection)
{
    // Send and receive messages here
}

Com a conexão, o próximo passo é criar um canal de mensagens, assim:

var channel = connection.CreateModel();

Enviar mensagens

Depois de ter o canal de mensagens, você pode usá-lo para configurar filas, trocas e outras integrações de sua topologia de mensagens. Por exemplo, para criar uma fila, use este código:

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

Você usa o BasicPublish método para enviar uma mensagem para essa fila, mas a mensagem espera que o corpo seja uma matriz de bytes:

var body = Encoding.UTF8.GetBytes("Getting all items in the catalog.");

channel.BasicPublish(exchange: string.Empty,
    routingKey: "catalogEvents",
    basicProperties: null,
    body: body);

Receber mensagens

Na integração de recebimento, você cria o canal de mensagens e a fila da mesma forma que para o remetente. Verifique se o nome da fila corresponde ao que você criou na integração de envio. Caso contrário, você criará duas filas separadas e as mensagens não chegarão ao destino correto.

Você deve criar um novo EventingBasicConsumer() método e registrar um método para manipular o Received evento:

var consumer = new EventingBasicConsumer(channel);
consumer.Received += ProcessMessageAsync;

O manipulador de mensagens usa um BasicDeliverEventArgs objeto para obter as propriedades da mensagem, incluindo o corpo da mensagem. Você deve se lembrar de desserializar o corpo da mensagem:

private void ProcessMessageAsync(object? sender, BasicDeliverEventArgs args)
{
    string messagetext = Encoding.UTF8.GetString(args.Body.ToArray());
    logger.LogInformation("The message is: {text}", messagetext);
}

Finalmente, para verificar a fila de novas mensagens, chame o BasicConsume() método;

channel.BasicConsume(queue:  queueName,
                    autoAck: true, 
                    consumer: consumer);

Mais informações