I have a Java App and a NodeJS App both using a single Azure Service Bus Message Queue.
I witness some strange effects with my clients, as follow.
JAVA MESSAGE PRODUCER (using QPID libraries per Azure JMS tutorial):
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());
OUTPUT: Sent message with JMSMessageID = ID:2414932965987073843
NODEJS MESSAGE CONSUMER:
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' }
If I compare that to a message inserted into the queue via serviceBus.sendQueueMessage(), then the properties look like this:
{ 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) } }
So content type is different to start with - why? - and then where does the strange garbage in the body of the first message payload come from: @ string\b3http://schemas.microsoft.com/2003/10/Serialization/� Is that the result of serialization? How can this be mitigated?
Find the code as well here: http://pastebin.com/T9RTFRBk
The Azure Service Bus supports two different protocols: AMQP and HTTP. The Java/JMS using qpid libs is using AMQP protocal for ServiceBus. However, the ServiceBus REST APIs wrapped in NodeJS thur HTTP protocol.
Details for AMQP support in Service Bus, please refer to https://azure.microsoft.com/en-us/documentation/articles/service-bus-amqp-overview/ .
And for REST APIs of ServiceBus, please refer to https://msdn.microsoft.com/en-us/library/azure/hh780717.aspx .
AMQP is a binary, application layer protocol, designed to efficiently support a wide variety of messaging applications and communication patterns. - from WikiPedia
But the HTTP is a text protocol.
The message format is as below, please refer to the section Message Format
of the aritifact http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#section-message-format . And the AMQP specification can be refered to 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
So the messages sent in Java or sent in NodeJS were serialized to different results.
The content \\uXXXX
formated in the content of body from AMQP is Unicode Charater.
The Unicode Charater \
is Acknowledge controll charater, please refer to https://en.wikipedia.org/wiki/Acknowledge_character to know it.
And the Unicode Charater \
is Substitute controll charater, please refer to https://en.wikipedia.org/wiki/Substitute_character .
They are limit the start and end of the metadata in the message header.
We have encountered the exact same issue, though in a somewhat more involved example using a Camel based producer. Due to changes in our environment we started to encounter these issues.
The issue here is how the REST service is interpreting the JMS message when it is encoding the HTTP response to the node client.
We've found that JmsTextmessage for some reason, not fully clear, are assumed to be of type "application/xml" and the content will be forwarded as such. Hence the OUTPUT you get in your example.
If instead using a JmsByteMessage, the content is interpreted as "application/octet-stream" and not mangled in transfer.
So try something along the lines of:
BytesMessage message = sendSession.createBytesMessage();
String body = "Test AMQP message from JMS";
message.writeBytes(body.getBytes(StandardCharsets.UTF_8));
sender.send(message);
We use this in order to transfer JSON encoded data to be interpreted by a Node.js client.
I had the same issue with the message body being prefixed by this "@\string\\b3http://schemas.microsoft.com/2003/10/Serialization/\".
I was using Nodejs, with the azure-iot-device-mqtt and azure-iot-device packages, to send messages to IoT hub. I was using a Stream Analytics Job to receive the messages from IoT hub and publish them to a queue. I was using Nodejs, with the amqp10 package, to receive the events from the queue.
The problem was not caused by the way I was sending or receiving the messages. Rather, the problem was with the Stream Analytics compatibility level! Compatibility level 1.0 (the default at least when I deployed) uses the DataContractSerializer which serializes the message into an XML stream! Microsoft changed (fixed) this with compatibility level 1.1. So you may just need to change the compatibility level (CONFIGURE->Compatibility level) for your Stream Analytics job to 1.1.
The message sent by JMS is actually in .NET Binary XML Format (MC-NBFX), as specified here . I think this is what you get when you try to serialise an object using a DataContractSerializer with XmlDictionaryWrite.CreateBinaryWriter (although I know nothing about .NET).
Quoting the message body from above for quick reference, and replacing Unicode characters with their hex equivalent (eg
to \x06
) and \b
(backspace escape) with its ASCII code 0x08 (BS):
@\x06string\x083http://schemas.microsoft.com/2003/10/Serialization/�\x1aTest AMQP message from JMS
string
.<string>
element, and indeed it is, again encoded as a variable-length string, with the length byte 3
(0x33 or decimal 51) and 51 characters of URL.Test AMQP message from JMS
.string
element, ie </string>
in XML text.So the equivalent XML text would be this:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Test AMQP message from JMS</string>
There are libraries that can decode this for you, for example libnbfx (C++) or msbin (Python).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.