2013-02-25 165 views
6

在我的测试应用程序中,我可以看到处理异常的消息被自动插入默认的EasyNetQ_Default_Error_Queue,这非常棒。然后,我可以使用Hosepipe成功转储或重新发送这些消息,这也可以正常工作,但需要下降到命令行并针对Hosepipe和RabbitMQ API调用以清除重试消息的队列。有没有简单的方法来订阅EasyNetQ中的默认错误队列?

所以我想我的应用程序最简单的方法是只订阅错误队列,所以我可以使用相同的基础结构重新处理它们。但在EastNetQ中,错误队列似乎很特殊。我们需要使用适当的类型和路由ID认购,所以我不知道这些值应该是什么错误队列:

bus.Subscribe<WhatShouldThisBe>("and-this", ReprocessErrorMessage);

我可以使用简单的API订阅错误队列,或者我需要挖掘到advanced API

如果我的原始邮件的类型是TestMessage,然后我想能够做这样的事情:

bus.Subscribe<ErrorMessage<TestMessage>>("???", ReprocessErrorMessage);

其中ErrorMessage是EasyNetQ提供包裹所有错误的类。这可能吗?

回答

3

不能使用简单的API订阅错误队列,因为它不遵循EasyNetQ队列类型命名约定 - 也许在这个时候,应该是固定的;)

但高级API工作正常。你不会得到原始的消息,但很容易获得JSON表示,你可以很容易地使用它来解序列化(使用Newtonsoft.JSON)。这里是你的,申购代码应该是什么样子的例子:我不得不修复错误消息在EasyNetQ编写代码之前,这个工作一个小错误,所以请尝试之前得到一个版本> = 0.9.2.73

[Test] 
[Explicit("Requires a RabbitMQ server on localhost")] 
public void Should_be_able_to_subscribe_to_error_messages() 
{ 
    var errorQueueName = new Conventions().ErrorQueueNamingConvention(); 
    var queue = Queue.DeclareDurable(errorQueueName); 
    var autoResetEvent = new AutoResetEvent(false); 

    bus.Advanced.Subscribe<SystemMessages.Error>(queue, (message, info) => 
    { 
     var error = message.Body; 

     Console.Out.WriteLine("error.DateTime = {0}", error.DateTime); 
     Console.Out.WriteLine("error.Exception = {0}", error.Exception); 
     Console.Out.WriteLine("error.Message = {0}", error.Message); 
     Console.Out.WriteLine("error.RoutingKey = {0}", error.RoutingKey); 

     autoResetEvent.Set(); 
     return Task.Factory.StartNew(() => { }); 
    }); 

    autoResetEvent.WaitOne(1000); 
} 

出来。你可以看到代码示例工程here

+0

感谢您的帮助迈克。你认为为此公开一个友好的包装会是一个好主意吗?默认情况下,简单的API写入这个错误队列,所以对我来说它有一个机制可以透明地使用这些错误。即使使用上面的代码,我想我需要在错误消息处理程序('switch(error.BasicProperties.Type)')中使用某种switch语句,然后我可以将原始消息反序列化为正确的类型,这有点丑陋。如果我可以订阅我感兴趣的特定类型的错误,那将会很好。 – 2013-02-25 11:22:15

+0

顺便说一句我喜欢EastNetQ图书馆。感谢您的辛勤工作和出色的文档。 – 2013-02-25 11:22:48

+0

感谢您的好评!我已将您的建议添加到问题列表https://github.com/mikehadlow/EasyNetQ/issues/71,但我并不完全相信。 – 2013-02-25 15:34:31

0

代码:

与“富”的screwyness是因为如果我只是传递函数HandleErrorMessage2进入消费调用,它可以” (我参加了一个猜测)不知道它会返回一个void而不是一个Task,所以不能确定使用哪个超载。 (VS 2012) 分配给一个变种使它感到高兴。 您将希望通过配置对象来捕获调用的返回值以便取消订阅。

另请注意,有人使用系统对象名称(队列)而不是使其成为EasyNetQueue或某事,因此您必须添加使用澄清编译器,或完全指定它。

using Queue = EasyNetQ.Topology.Queue; 

    private const string QueueName = "EasyNetQ_Default_Error_Queue"; 
    public static void Should_be_able_to_subscribe_to_error_messages(IBus bus) 
    { 
    Action <IMessage<Error>, MessageReceivedInfo> foo = HandleErrorMessage2; 

    IQueue queue = new Queue(QueueName,false); 
    bus.Advanced.Consume<Error>(queue, foo); 
    } 

    private static void HandleErrorMessage2(IMessage<Error> msg, MessageReceivedInfo info) 
{ 
} 
相关问题