2017-07-03 46 views
2

背景资料的RabbitMQ EventBasicConsumer不工作

我(对电子邮件)在RabbitMQ的队列,并希望建立一个消费它。该队列被另一个.NET应用程序用于向客户发送电子邮件。我希望电子邮件逻辑能够放在.NET应用程序之外,并且还具有RabbitMQ提供的耐用性等优点。

发行

的.NET应用程序能够发布/电子邮件推到队列中,但我有困难,构建客户!这是我对消费者代码:

// A console app that would be turned into a service via TopShelf 
public void Start() 
{ 
    using (_connection = _connectionFactory.CreateConnection()) 
    { 
    using (var model = _connection.CreateModel()) 
    { 
     model.QueueDeclare(_queueName, true, false, false, null); 
     model.BasicQos(0, 1, false); 

     var consumer = new EventingBasicConsumer(model); 
     consumer.Received += (channelModel, ea) => 
     { 
     var message = (Email) ea.Body.DeSerialize(typeof(Email)); 
     Console.WriteLine("----- Email Processed {0} : {1}", message.To, message.Subject); 
     model.BasicAck(ea.DeliveryTag, false); 
     }; 
     var consumerTag = model.BasicConsume(_queueName, false, consumer); 
    } 
    } 
} 

上面的代码应该能够抓住关闭消息队列并处理它们(根据本official guide),但这没有发生。

+0

许多事情都可能出错。你如何发布消息(交换)?同样在你当前的代码中 - 在你创建你的客户之后(在'BasicConsume'后面),连接会立即关闭,所以你将无法得到任何消息。开始使用后不要立即处理您的连接。 – Evk

+0

@Evk发布者和消费者都是针对相同的交易所和队列,我确信这一点。但我认为你对连接处理是正确的,我会解决这个问题,并且看看它是否能够做到。 – Ciwan

+0

@Evk你是对的,处理连接是问题,请回复,我会标记为答案:) – Ciwan

回答

1

问题是过早的连接处置。人们经常认为BasicConsume是一个阻塞呼叫,但事实并非如此。它将几乎立即返回,而下一个声明将处理(关闭)频道和连接,这当然会取消您的订阅。所以要修复 - 将连接和模型存储在专用字段中,并仅在完成队列消耗时才处理它们。

+0

谢谢,就是这样。 – Ciwan

0

你说队列被另一个.Net应用程序使用,是另一个消费者吗?如果这是另一位消费者,那么您能否确认您使用的是哪种兑换?如果您希望多个消费者提取消息,请继续使用“FanOut”交换

+0

原来是@Evk建议的。 – Ciwan

相关问题