我使用Rebus创建了一个与Azure Service Bus相关的概念证明,但是我在解析从外部源放入队列的消息时遇到了一些问题。
我收到错误消息:
收到消息为空或缺席' rbs2-msg-id'头!
我已经浏览了GitHub并注意到这个列表,其中有人对RabbitMQ有类似的问题,建议使用装饰器:
https://github.com/rebus-org/Rebus/issues/508
但是,我不确定如何仅针对消息ID执行此操作。
我失败的一个选项实际上是修改Rebus.AzureTransport代码来执行此操作:
var messageId = headers.GetValueOrNull(Headers.MessageId);
if (string.IsNullOrEmpty(messageId))
{
messageId = Guid.NewGuid().ToString();
headers[Headers.MessageId] = messageId;
}
但是更喜欢另类!
我注意到的另一件事是BrokeredMessage就像这样放在ASB上:
var message = new BrokeredMessage("<xml>This is a test message: " + DateTime.Now+ "</xml>");
Rebus接收时未正确序列化。我收到以下错误:
处理ID为db13880d-124c-4ed5-993e-96faeca0f140的消息时出现未处理的异常1:System.Collections.Generic.KeyNotFoundException:找不到键&#39; rbs2-content-type&#39;
通过覆盖Serialiser,底层消息将会出现:
@ strin3http://schemas.microsoft.com/2003/10/Serialization/?6这是测试信息:06/12/2016 07:44:21
所以我不确定我做错了什么。
提前致谢。
答案 0 :(得分:0)
嗯......正如错误消息所说,传入的消息不包含足够的信息,以便Rebus处理它。
此外,Rebus的Azure Service Bus传输要求将消息内容作为Stream
发送,以避免将包含的字节封装在XML结构中(这是Azure Service Bus驱动程序所执行的操作)默认情况下)。
如果我是你,我可能不会使用Rebus从不包含Rebus发送的消息的队列接收消息。或者,我可能会这样做 - 但前提是传入的消息很容易适应Rebus格式。
虽然实现这一点可能有点麻烦,因为 - 正如你已经正确观察到的那样 - 它需要存在某些标题,这些标题对Rebus如何在处理尝试之间跟踪它,如何反序列化起作用它,如果要调用bus.Reply
那么回复的地方等等。所以我仍然可能最终没有这样做:)
我建议你这样做:
while(true)
{
var message = GetNextMessageOrNullFromQueue();
if (message == null) continue;
UnwrapMessageAndSendWithRebusToRebusQueue(message);
}
这样编码您自己的接收循环以接收自定义格式的Azure Service Bus消息,将其实际处理(可能还从XML文本反序列化为对象?)委派给Rebus端点。
这通常是与外部事物集成的首选方式,因为它保持了在应用程序外部和内部之间来回桥接的逻辑,而不是渗透到应用程序中。