互操作性Azure服务总线消息队列消息
我有一个Java应用程序和一个NodeJS应用程序都使用一个单一的Azure服务总线消息队列。
我跟我的客户见证了一些奇怪的效果,如下所示。
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消息消费者:
serviceBus.receiveQueueMessage(queue, {timeoutIntervalInS: timeOut, isReceiveAndDelete: true}, function(err, message) { if(message !==null)console.log(util.inspect(message, {showHidden: false, depth: null})); });
OUTPUT:
{ 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) } }
所以内容types是不同的开始 – 为什么? – 然后在第一个消息有效载荷的主体中的奇怪的垃圾从哪里来: @ \ u0006string \ b3http://schemas.microsoft.com/2003/10/Serialization/ \ u001a这是序列化的结果? 这怎么能被减轻?
在这里find代码: http : //pastebin.com/T9RTFRBk
Azure服务总线支持两种不同的协议:AMQP和HTTP。 使用qpid库的Java / JMS使用AMQP协议ServiceBus。 但是,NodeJS中包装的ServiceBus REST API通过HTTP协议。
Service Bus中的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是一种二进制应用层协议,旨在有效支持各种消息应用和通信模式。 – 来自WikiPedia
但是HTTP是一个文本协议。
消息格式如下,请参考aritifact的Message Format
部分http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os .html#section-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发送的消息被序列化为不同的结果。
\uXXXX
格式的内容在Unicode内容格式化为Unicode特性。
Unicode \u0006
是Acknowledge controll特性,请参阅https://en.wikipedia.org/wiki/Acknowledge_character了解它。
Unicode \u001a
是替代控制字符,请参阅https://en.wikipedia.org/wiki/Substitute_character 。
它们限制了消息头中元数据的开始和结束。
我们遇到了完全相同的问题,尽pipe在使用基于Camel的生产者的一个更多的例子中。 由于我们环境的变化,我们开始遇到这些问题。
这里的问题是REST服务在对节点客户机的HTTP响应进行编码时如何解释JMS消息。
我们发现JmsTextmessage出于某种原因,并不完全清楚,被认为是“application / xml”types,并且内容将被转发。 因此你在你的例子中得到了OUTPUT。
如果改为使用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);
我们使用这个来传输JSON编码的数据,由Node.js客户端解释。