我正在尝试将RabbitMQ集成为现有微服务项目中的消息传递队列。我目前编写了一个Send
函数,该函数接收字符串消息并将其发布到命名队列。
现在,我正在尝试编写Receive
函数,这是到目前为止的内容:
public static void Receive(string queueName)
{
using (IConnection connection = GetConnection(LOCALHOST))
{
using (IModel channel = connection.CreateModel())
{
channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null);
// Don't dispatch a new message to a consumer until it has processed and acknowledged the previous one.
channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
var consumer = new EventingBasicConsumer(channel); // non-blocking
consumer.Received += (model, e) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
// At this point, I can do something with the message.
};
channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);
}
}
}
我认为还可以,但是我对一些我困惑的部分有一些疑问。
1)我不太了解Received
字段是什么,为什么它要附加一个匿名函数,我们在接收到匿名函数后会进行实际工作。
2)BasicConsume
在做什么?实际接收会发生在BasicConsume
还是Received
字段中吗? BasicConsume
字段分配后是否必须发生Received
?
3)最后,我有两个需要从队列使用的微服务。我以为我可以分别在这两个微服务中分别调用Receive
。它会持续监听消息还是我需要将Receive
调用置于while循环中?
感谢您的帮助和启发。
答案 0 :(得分:2)
1)Received
实际上是一个事件。因此,调用consumer.Received += (model, e) => {};
即表示您正在订阅它,但这不一定是一个匿名函数,它可能像:
consumer.Received += OnReceived;
....
private static void OnReceived(object model, BasicDeliverEventArgs e)
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
// At this point, I can do something with the message.
}
它在您每次收到消息时执行。
2)BasicConsume
启动您之前创建的频道的使用者。将执行“已接收”中的功能。
3)在使用EventingBasicConsumer
的情况下,他们将继续收听该频道。可能需要为另一种Consumer