如果我连接到RabbitMQ并使用EventingBasicConsumer监听事件,我怎么能判断我是否已从服务器断开连接?
我知道有一个Shutdown事件,但如果我拔下网线以模拟故障,它就不会触发。
我还尝试了模型上的ModelShutdown事件和CallbackException,但似乎都没有。
EDIT ----- 我标记为答案的那个是正确的,但它只是我解决方案的一部分。 RabbitMQ中还内置了HeartBeat功能。服务器在配置文件中指定它。默认为10分钟,但您当然可以更改它。
客户端还可以通过在ConnectionFactory实例上设置RequestedHeartbeat值来请求心跳的不同间隔。
答案 0 :(得分:5)
我猜你正在使用c#库吗? (但即便如此,我认为其他人也有类似的事件)。
您可以执行以下操作:
public class MyRabbitConsumer
{
private IConnection connection;
public void Connect()
{
connection = CreateAndOpenConnection();
connection.ConnectionShutdown += connection_ConnectionShutdown;
}
public IConnection CreateAndOpenConnection() { ... }
private void connection_ConnectionShutdown(IConnection connection, ShutdownEventArgs reason)
{
}
}
答案 1 :(得分:0)
这是一个例子,但明确的答案是引导我的。
var factory = new ConnectionFactory
{
HostName = "MY_HOST_NAME",
UserName = "USERNAME",
Password = "PASSWORD",
RequestedHeartbeat = 30
};
using (var connection = factory.CreateConnection())
{
connection.ConnectionShutdown += (o, e) =>
{
//handle disconnect
};
using (var model = connection.CreateModel())
{
model.ExchangeDeclare(EXCHANGE_NAME, "topic");
var queueName = model.QueueDeclare();
model.QueueBind(queueName, EXCHANGE_NAME, "#");
var consumer = new QueueingBasicConsumer(model);
model.BasicConsume(queueName, true, consumer);
while (!stop)
{
BasicDeliverEventArgs args;
consumer.Queue.Dequeue(5000, out args);
if (stop) return;
if (args == null) continue;
if (args.Body.Length == 0) continue;
Task.Factory.StartNew(() =>
{
//Do work here on different thread then this one
}, TaskCreationOptions.PreferFairness);
}
}
}
有关此事的一些注意事项。
我正在使用#作为主题。这抓住了一切。通常你想限制一个主题。
我设置了一个名为" stop"的变量。确定过程何时结束。您会注意到循环会一直运行,直到该变量为真。
如果没有新消息,Dequeue等待5秒然后离开而不获取数据。这是为了确保我们监听该停止变量并在某些时候实际退出。根据自己的喜好更改值。
当收到消息时,我在新线程上生成处理代码。当前线程被保留用于仅监听rabbitmq消息,如果处理程序需要很长时间才能处理,我不希望它减慢其他消息的速度。根据您的实施情况,您可能需要也可能不需要。但是要小心编写代码来处理消息。如果运行需要一分钟,并且您在亚秒级获得消息,则内存不足或至少会出现严重的性能问题。