I'm new in RabbitMQ, and I using Publisher Confirm to ensure that message is delivered successfully.
But I'm facing a strange behavior, which is when I publish a message and take a sequenceNumber the function channel.BasicAcks is fired n times which n is the DeliveryTag, so if the DeliveryTag for this message is 5 the function channel.BasicAcks is fired 5 times?!!
And here is my code:
IModel channel = _customRabbitMQ.GetChannel();
IBasicProperties properties = _customRabbitMQ.GetBasicProperties();
ulong sequenceNumber = channel.NextPublishSeqNo;
message.SequenceNumber = sequenceNumber.ToString();
_context.Messages.Update(message);
await _context.SaveChangesAsync();
try
{
_customRabbitMQ.AddOutstandingConfirm(sequenceNumber, message.Id);
channel.BasicPublish(message.ExchangeName, message.RoutingKey, properties, Encoding.UTF8.GetBytes(JsonSerializer.Serialize(message)));
Console.WriteLine("Message Published");
}
catch (Exception ex)
{
// TODO: log to custom logger here
Console.WriteLine($"Error => {ex.Message}");
}
channel.BasicAcks += async (sender, ea) =>
{
try
{
Console.WriteLine("Message Confirmed");
using var scope = _provider.CreateScope();
var _context = scope.ServiceProvider.GetService<Data.DataContext>();
var _customRabbitMQ = scope.ServiceProvider.GetService<CustomRabbitMQ>();
Guid messageId = _customRabbitMQ.GetOutstandingConfirm(ea.DeliveryTag);
Message message = await _context.Messages.Where(m => m.Id == messageId).FirstOrDefaultAsync();
message.Status = MessageStatuses.INQUEUE;
_context.Messages.Update(message);
await _context.SaveChangesAsync();
_customRabbitMQ.RemoveOutstandingConfirm(ea.DeliveryTag);
}
catch (Exception ex)
{
Console.WriteLine($"Error => {ex.Message}");
}
};
channel.BasicNacks += (sender, ea) =>
{
Console.WriteLine("Message Not Confirmed");
_customRabbitMQ.RemoveOutstandingConfirm(ea.DeliveryTag);
};
}
So, why this happening and how to stop it and make it confirm only one time?
Thanks in advance.