Exemplos de produtor e consumidor | RabbitMQ
- Exemplos de produtor e consumidor | RabbitMQ
Propriedades do produtor
danger
Quem deve criar a fila: 🔗 Clique aqui Routing-Key e Binding-Key: 🔗 Clique aqui
static void Main(string[] args)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
string message = "This is sample message";
var body = Encoding.UTF8.GetBytes(message);
var properties = channel.CreateBasicProperties();
properties.Persistent = true; // 🔹 mensagem persistente
properties.ContentType = "text/plain";
properties.DeliveryMode = 2; // 2 = persistente
properties.Timestamp = new AmqpTimestamp(DateTimeOffset.UtcNow.ToUnixTimeSeconds());
channel.BasicPublish(
exchange: "",
routingKey: "sample",
basicProperties: properties,
body: body
);
Console.WriteLine($"[x] Sent a message : {message}");
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
Versão <= 6.x
Propriedades do consumidor
static void Main(string[] args)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(
queue: "sample",
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 a message : {message}");
};
channel.BasicConsume(
queue: "sample",
autoAck: true,
//A execução de uma tarefa pode levar alguns segundos. Você pode se perguntar o que acontece se um dos consumidores iniciar uma longa tarefa e morrer com ela apenas parcialmente concluída. Com nosso código atual, uma vez que o RabbitMQ entrega uma mensagem ao consumidor, ele imediatamente a marca para exclusão. Nesse caso, se você matar um trabalhador, perderemos a mensagem que estava apenas processando. Também perderemos todas as mensagens que foram despachadas para esse trabalhador em particular, mas que ainda não foram tratadas.
//Mas não queremos perder nenhuma tarefa. Se um trabalhador morrer, gostaríamos que a tarefa fosse entregue a outro trabalhador.
//Para garantir que uma mensagem nunca seja perdida, o RabbitMQ suporta reconhecimentos de mensagens. Uma confirmação é enviada de volta pelo consumidor para informar ao RabbitMQ que uma determinada mensagem foi recebida, processada e que o RabbitMQ está livre para excluí-la
consumer: consumer);
Console.WriteLine(" Press any key to exit.");
Console.ReadKey();
}
}
Versão >= 7.x
Propriedades do produtor
using RabbitMQ.Client;
using System.Text;
static async Task Main(string[] args)
{
var factory = new ConnectionFactory()
{
Uri = new Uri("amqp://guest:guest@localhost:5672")
};
await using var connection = await factory.CreateConnectionAsync();
await using var channel = await connection.CreateChannelAsync();
string message = "This is sample message";
var body = Encoding.UTF8.GetBytes(message);
// ✅ Instanciação direta (novo padrão)
var properties = new BasicProperties
{
ContentType = "text/plain",
DeliveryMode = DeliveryModes.Persistent,
MessageId = Guid.NewGuid().ToString(),
Timestamp = new AmqpTimestamp(DateTimeOffset.UtcNow.ToUnixTimeSeconds()),
Headers = new Dictionary<string, object>
{
{ "origin", "producer-7x" }
}
};
await channel.BasicPublishAsync(
exchange: "",
routingKey: "sample",
mandatory: false,
basicProperties: properties,
body: body
);
Console.WriteLine($"[x] Sent: {message}");
}
Propriedades do consumidor - Exemplo de um Worker
info
- A API do
RabbitMQ.Clientmudou no .NET 7+ e a interfaceIModelfoirenomeada para IChannelna versão7.xdo cliente para refletir melhor o modelo de AMQP 0‑9‑1. EventingBasicConsumer (sincrono)se transformou emAsyncEventingBasicConsumer (assíncrono)
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
public sealed class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IConfiguration _configuration;
private IConnection? _connection;
private IChannel? _channel;
private string? _queue;
public Worker(
ILogger<Worker> logger,
IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Worker iniciando (RabbitMQ Consumer)");
string? connectionString = _configuration.GetConnectionString("rabbitmq");
if (string.IsNullOrWhiteSpace(connectionString))
throw new InvalidOperationException("ConnectionStrings:rabbitmq não configurada.");
ConnectionFactory factory = new ConnectionFactory
{
Uri = new Uri(connectionString),
AutomaticRecoveryEnabled = true,
NetworkRecoveryInterval = TimeSpan.FromSeconds(10),
};
_connection = await factory.CreateConnectionAsync(cancellationToken);
_channel = await _connection.CreateChannelAsync(cancellationToken: cancellationToken);
_queue = _configuration["RabbitMq:Queue"];
if (string.IsNullOrWhiteSpace(_queue))
throw new InvalidOperationException("RabbitMq:Queue não configurada.");
_ = await _channel.QueueDeclareAsync(queue: _queue, durable: true, exclusive: false, autoDelete: false, arguments: null, cancellationToken: cancellationToken);
await _channel.BasicQosAsync(prefetchSize: 0, prefetchCount: ushort.Parse(_configuration["RabbitMq:PrefetchCount"] ?? "10"), global: false, cancellationToken: cancellationToken);
await base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
AsyncEventingBasicConsumer consumer = new AsyncEventingBasicConsumer(_channel!);
consumer.ReceivedAsync += HandleMessageAsync;
_ = await _channel!.BasicConsumeAsync(queue: _queue!, autoAck: false, consumer: consumer, cancellationToken: stoppingToken);
_logger.LogInformation("Consumer conectado à fila {Queue}", _queue);
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(1000, stoppingToken); // apenas para manter o serviço ativo
}
}
private async Task HandleMessageAsync(object sender, BasicDeliverEventArgs ea)
{
try
{
string message = Encoding.UTF8.GetString(ea.Body.ToArray());
_logger.LogInformation("Mensagem recebida: {Message}", message);
// 🔹 Simula processamento
await Task.Delay(500);
await _channel!.BasicAckAsync(ea.DeliveryTag, multiple: false);
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao processar mensagem");
await _channel!.BasicNackAsync(
deliveryTag: ea.DeliveryTag,
multiple: false,
requeue: false);
}
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Worker parando");
_ = (_channel?.CloseAsync(cancellationToken));
_ = (_connection?.CloseAsync(cancellationToken: cancellationToken));
await base.StopAsync(cancellationToken);
}
public override void Dispose()
{
_channel?.Dispose();
_connection?.Dispose();
base.Dispose();
}
}