我有一个非常简单的客户端,我希望每周7天每天24小时都可以使用消息。它在Windows进程中运行。
我对服务器和接收消息没有任何问题,它只是客户端。
行为如下:
如果我重新开始连接,则可以正常工作。经过一段时间,也许几个小时,我的客户处于一个奇怪的状态;它包含的连接“保持”未包装的消息。
换句话说,使用网络管理界面,我看到我总共有2条未经处理的消息。看着我的联系,我看到2条未经处理的消息传播开来。
但是没有处理过。
最终,我的连接被杀死,没有异常或日志消息被触发。这会将所有消息置于就绪状态。
我解决问题的第一个尝试是添加一个简单的外部循环来检查IModel,IChannel和QueueingBasicConsumer的i-vars的状态。但是,即使在Web管理员报告没有活动连接之后,IModel / IChannel的IsOpen也会报告为真,并且QueueingBasicConsumer的IsRunning也始终报告为真。
显然,我需要另一种方法来检查连接是否“有效”。
总而言之,事情最初运作良好。最终,我进入一个奇怪的状态,我的诊断检查毫无意义,发送到服务器的消息得到解除,并分散在任何现有的连接上。很快,我的连接被杀死,没有调试或抛出异常,我的诊断检查仍然报告事情是犹太教。
任何帮助或最佳做法将不胜感激。我已经阅读了心跳和IsOpen'竞赛'条件,建议使用BasicQos并检查异常,但我想先了解发生了什么。
这是我开球的地方:
private void StartMessageLoop(string uri, string queueName) {
this.serverUri = uri;
this.queueName = queueName;
Connect(uri);
Task.Factory.StartNew(()=> MessageLoopTask(queueName));
}
以下是我的联系方式:
private void Connect(string serverAddress) {
ConnectionFactory cf = new ConnectionFactory();
cf.Uri = serverAddress;
this.connection = cf.CreateConnection();
this.connection.ConnectionShutdown += new ConnectionShutdownEventHandler(LogConnClose);
this.channel = this.connection.CreateModel();
}
这是无限循环开始的地方:
private void MessageLoopTask(string queueName) {
consumer = new QueueingBasicConsumer(channel);
String consumerTag = channel.BasicConsume(queueName, false, consumer);
while (true) {
try {
BasicDeliverEventArgs e = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
IBasicProperties props = e.BasicProperties;
byte[] body = e.Body;
string messageContent = Encoding.UTF8.GetString(body);
bool result = this.messageProcessor.ProcessMessage(messageContent);
if(result){
channel.BasicAck(e.DeliveryTag, false);
}
else{
channel.BasicNack(e.DeliveryTag, false, true);
// log
}
}
catch (OperationInterruptedException ex) {
// log
break;
}
catch(Exception e) {
// log
break;
}
}
// log
}
此致 戴恩