我在RabbitMQ中有一些关于编码的问题......我不是这个世界的新手,并且根据我提供给我实施的设计提出了问题......
设计说发布者需要等待并知道消费者的处理何时完成,以便在客户端执行某项任务(取决于成功/失败)。
我尝试了下面的代码但是在没有发送任何Ack或Nack的情况下立即从队列中删除了消息。我很困惑
发布商代码:
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.QueueDeclare("test", durable, false, false, null);
channel.TxSelect();
var properties = channel.CreateBasicProperties();
properties.SetPersistent(true);
string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish("", "test", properties, body);
channel.TxCommit();
Console.WriteLine(" [x] Sent {0}", message);
}
}
消费者代码
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.QueueDeclare("test", durable, false, false, null);
var consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume("test", true, consumer);
Console.WriteLine(" [*] Waiting for messages." +
"To exit press CTRL+C");
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] Received {0}", message);
}
}
}
注意:我意识到channel.BasicConsume("test", true, consumer);
有noAck为true。我将其更改为channel.BasicConsume("test", false, consumer);
当我使用channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
时,我可以看到消息已从队列中删除但是,Publisher如何知道消费者已成功处理它?</ p>
答案 0 :(得分:1)
这是一个重复的问题。检查此主题,这是一个类似的问题,答案正确:Why doesn't Channel.waitForConfirmsOrDie block?
答案 1 :(得分:1)
如何确保发布服务器仅在消费者准备好处理时才向服务器发送消息?
你做不到。更重要的是,你不应该。使用消息传递架构的关键是忘记这类问题。检查this。
此外,RabbitMQ将为您存储此消息,直到有人准备在队列持久时处理它们。
但是,Publisher如何知道消费者成功处理了它?
不,不会。 ack只在RabbitMQ和您的消费者之间或RabbitMQ和您的制作人之间。有关ack / nack的详细信息,请查看this。
如果我能正确理解你,你想在这里实现的是一种“健谈”的架构,消费者也是出版商“响应消息”的制作者,像“嘿,我是”这样的消息完成消息XX,一切都很好“。
这样做的简单方法是将您的消费者设置为生产者,并将您的生产者设置为消费者。您只需要在消息中添加guid或某种唯一ID,当您完成它后,您将在另一个具有该id作为内容的队列上发送消息,以通知原始发布者(这是一个消费者)这个“响应”队列)工作已成功完成。
希望有所帮助:)
答案 2 :(得分:0)