我有一个使用单个Azure Service Bus Message Queue的Java App和NodeJS App。
我与客户见证了一些奇怪的效果,如下所示。
JAVA MESSAGE PRODUCER(每个Azure JMS教程使用QPID库):
TextMessage message = sendSession.createTextMessage();
message.setText("Test AMQP message from JMS");
long randomMessageID = randomGenerator.nextLong() >>>1;
message.setJMSMessageID("ID:" + randomMessageID);
sender.send(message);
System.out.println("Sent message with JMSMessageID = " + message.getJMSMessageID());
输出: 使用JMSMessageID = ID发送的消息:2414932965987073843
NODEJS MESSAGE消费者:
serviceBus.receiveQueueMessage(queue, {timeoutIntervalInS: timeOut, isReceiveAndDelete: true}, function(err, message) {
if(message !==null)console.log(util.inspect(message, {showHidden: false, depth: null}));
});
输出:
{ body: '@\u0006string\b3http://schemas.microsoft.com/2003/10/Serialization/�\u001aTest AMQP message from JMS',
brokerProperties:
{ DeliveryCount: 1,
EnqueuedSequenceNumber: 5000004,
EnqueuedTimeUtc: 'Wed, 04 Nov 2015 21:28:21 GMT',
MessageId: '2414932965987073843',
PartitionKey: '89',
SequenceNumber: 59672695067659070,
State: 'Active',
TimeToLive: 1209600,
To: 'moequeue' },
contentType: 'application/xml; charset=utf-8' }
如果我将其与通过serviceBus.sendQueueMessage()插入队列的消息进行比较,则属性如下所示:
{ body: 'test message',
brokerProperties:
{ DeliveryCount: 1,
EnqueuedSequenceNumber: 0,
EnqueuedTimeUtc: 'Wed, 04 Nov 2015 21:44:03 GMT',
MessageId: 'bc0a3d4f-15ba-434f-9fb0-1a3789885f8c',
PartitionKey: '734',
SequenceNumber: 37436171906517256,
State: 'Active',
TimeToLive: 1209600 },
contentType: 'text/plain',
customProperties:
{ message_number: 0,
sent_date: Wed Nov 04 2015 21:44:03 GMT+0000 (UTC) } }
所以内容类型开头不同 - 为什么? - 然后第一个消息有效负载正文中的奇怪垃圾来自哪里: @ \ u0006string \ b3http://schemas.microsoft.com/2003/10/Serialization/ \ u001a 这是序列化的结果吗?如何减轻这种情况?
在这里找到代码: http://pastebin.com/T9RTFRBk
答案 0 :(得分:2)
Azure Service Bus支持两种不同的协议:AMQP和HTTP。使用qpid库的Java / JMS正在为ServiceBus使用AMQP协议。但是,ServiceBus REST API包含在NodeJS中的HTTP协议中。
服务总线中AMQP支持的详细信息,请参阅https://azure.microsoft.com/en-us/documentation/articles/service-bus-amqp-overview/。
对于ServiceBus的REST API,请参阅https://msdn.microsoft.com/en-us/library/azure/hh780717.aspx。
AMQP是一种二进制应用层协议,旨在高效地实现 支持各种消息传递应用程序和通信 图案。 - from WikiPedia
但HTTP是一种文本协议。
消息格式如下,请参阅aritifact http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#section-message-format的Message Format
部分。 AMQP规范可以参考http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-overview-v1.0-os.html。
Bare Message
|
.---------------------+--------------------.
| |
+--------+-------------+-------------+------------+--------------+--------------+--------+
| header | delivery- | message- | properties | application- | application- | footer |
| | annotations | annotations | | properties | data | |
+--------+-------------+-------------+------------+--------------+--------------+--------+
| |
'-------------------------------------------+--------------------------------------------'
|
Annotated Message
因此,用Java发送或在NodeJS中发送的消息被序列化为不同的结果。
来自AMQP的正文内容中形成的内容\uXXXX
是Unicode Charater。
Unicode Charater \u0006
是Acknowledge controll charater,请参考https://en.wikipedia.org/wiki/Acknowledge_character了解它。
Unicode Charater \u001a
是替代控制字符,请参阅https://en.wikipedia.org/wiki/Substitute_character。
它们限制了邮件头中元数据的开头和结尾。
答案 1 :(得分:0)
我们遇到了完全相同的问题,尽管在使用基于Camel的生产者的一个更为复杂的例子中。由于环境的变化,我们开始遇到这些问题。
这里的问题是REST服务在将HTTP响应编码到节点客户端时如何解释JMS消息。
我们发现JmsTextmessage由于某种原因(不完全清楚)被假定为“application / xml”类型,内容将被转发。因此,您在示例中得到的输出。
如果改为使用JmsByteMessage,则内容将被解释为“application / octet-stream”,并且不会在传输中被破坏。
所以尝试一下以下几点:
BytesMessage message = sendSession.createBytesMessage();
String body = "Test AMQP message from JMS";
message.writeBytes(body.getBytes(StandardCharsets.UTF_8));
sender.send(message);
我们使用它来传输由Node.js客户端解释的JSON编码数据。
答案 2 :(得分:0)
我遇到了同样的问题,邮件正文以“@ \ u0006string \ b3http://schemas.microsoft.com/2003/10/Serialization/ \ u0001”作为前缀。
我正在使用带有 azure-iot-device-mqtt 和 azure-iot-device 软件包的Nodejs向IoT集线器发送消息。我使用流分析作业从IoT中心接收消息并将其发布到队列中。我使用Nodejs和 amqp10 包来接收队列中的事件。
问题不是由我发送或接收邮件的方式引起的。相反,问题在于Stream Analytics兼容级别!兼容级别1.0(至少在我部署时是默认值)使用DataContractSerializer将消息序列化为XML流! Microsoft通过兼容级别1.1更改(修复)了这个问题。因此,您可能只需要将Stream Analytics作业的兼容级别(CONFIGURE->兼容级别)更改为1.1。