无法 JSON 解析从 Node.js 应用程序中的 Azure 服务总线收到的消息
Can't JSON parse message received from Azure Service Bus in Node.js app
这是我的 JS 代码,用于从 Azure 服务总线接收消息
function receiveMessage(serviceBusTopic, serviceBusSubscriber, callback) {
serviceBus.receiveSubscriptionMessage(serviceBusTopic, serviceBusSubscriber,
{ isPeekLock: true }, function (error, lockedMessage) {
if (!error) {
try {
const receivedMessage = JSON.parse(lockedMessage.body);
console.log('receivedMessage', receivedMessage);
if (!_.isEqual(receivedMessage.Type, messageType.USERPROFILES_USER_UPDATED)) {
return;
}
//Message received and locked
callback(receivedMessage);
serviceBus.deleteMessage(lockedMessage, function (deleteError) {
if (!deleteError) {
// Message deleted
console.log('message has been deleted.');
}
});
}
catch (error) {
console.log('Start debugging');
console.log(lockedMessage.body);
}
当我收到一条消息时,它的编码很奇怪,JSON.parse 引发异常。
lockedMessage 输出为:
{ body: '@\fbase64Binary\b3http://schemas.microsoft.com/2003/10/Serialization/�s\u0002{"Type":"SomeEvent"�\u0001}',
brokerProperties:
{ DeliveryCount: 9,
EnqueuedSequenceNumber: 0,
EnqueuedTimeUtc: 'Thu, 16 Nov 2017 23:50:16 GMT',
LockToken: '6e3e311f-0fe9-4366-844d-18046fd000db',
LockedUntilUtc: 'Fri, 17 Nov 2017 00:10:46 GMT',
MessageId: 'nil',
PartitionKey: '1d84084f-65af-4a33-bb30-62d97d85557d',
SequenceNumber: 61643019899633670,
SessionId: '1d84084f-65af-4a33-bb30-62d97d85557d',
State: 'Active',
TimeToLive: 1566804.069 },
location: '',
contentType: 'application/xml; charset=utf-8',
customProperties: { 'strict-transport-security': NaN, connection: NaN } }
消息来自 .NET Core 服务,该服务使用以下代码发送:
var payload = JsonConvert.SerializeObject(SomeEvent);
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
topicClient.SendAsync(serviceBusMessage).Wait();
为什么 Node.js 无法解析邮件?另一个 .NET 应用程序可以毫无问题地接收相同的消息。
为避免这种情况,您需要在从 .NET Core 服务发送消息时将 ContentType
设置为 text/plain
。所以它应该是这样的:
var payload = JsonConvert.SerializeObject(SomeEvent);
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload))
{
ContentType = "text/plain"
};
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
topicClient.SendAsync(serviceBusMessage).Wait();
在此 article 中,他们解释了 .NET 的问题和解决方案。
更新:
经过一番探索,当我使用 .NET Core 或 .NET 通过标准库 Microsoft.Azure.ServiceBus
发送消息时,无论是否指定 ContentType
都不会发生这种情况。
这是我发送消息的 C# 代码:
class Program
{
static void Main(string[] args)
{
string connectionString = "Endpoint=sb://...";
var client = new TopicClient(connectionString, "MyTopic");
var payload = JsonConvert.SerializeObject(new DemoMessage() { Title = $"hello core!!! {DateTime.Now}" });
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
client.SendAsync(serviceBusMessage).Wait();
}
private class DemoMessage
{
public DemoMessage()
{
}
public string Title { get; set; }
}
}
这是我的 Node.js 接收消息的代码:
var azure = require('azure');
var serviceBusService = azure.createServiceBusService("Endpoint=sb://...");
serviceBusService.receiveSubscriptionMessage('MyTopic', 'sub1', { isPeekLock: true }, function(error, lockedMessage) {
if(!error) {
console.log(lockedMessage);
serviceBusService.deleteMessage(lockedMessage, function (deleteError){
if(!deleteError){
// Message deleted
console.log('message has been deleted.');
}
})
}
});
lockedMessage
输出为:
这仅在我使用 .NET 和 SDK WindowsAzure.ServiceBus
时发生,代码如下:
class Program
{
static void Main(string[] args)
{
string connectionString = "Endpoint=sb://...";
var client = TopicClient.CreateFromConnectionString(connectionString, "MyTopic");
var payload = JsonConvert.SerializeObject(new DemoMessage() { Title = $"hello core!!! {DateTime.Now}" });
var serviceBusMessage = new BrokeredMessage(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
client.Send(serviceBusMessage);
}
private class DemoMessage
{
public DemoMessage()
{
}
public string Title { get; set; }
}
}
现在,lockedMessage
输出是:
所以,我认为您收到的消息是从另一个 .NET 客户端发送的,我建议您在 Node.js.
中测试之前清除主题中的所有消息
我也运行关注这个问题。如果您使用的是流分析,则其兼容性级别可能是导致此问题的原因。流分析兼容级别 1.0 使用 XML 序列化程序生成您看到的 XML 标记。兼容级别 1.1 "fixes" 这个问题。
在这里查看我之前的回答:。
这是我的 JS 代码,用于从 Azure 服务总线接收消息
function receiveMessage(serviceBusTopic, serviceBusSubscriber, callback) {
serviceBus.receiveSubscriptionMessage(serviceBusTopic, serviceBusSubscriber,
{ isPeekLock: true }, function (error, lockedMessage) {
if (!error) {
try {
const receivedMessage = JSON.parse(lockedMessage.body);
console.log('receivedMessage', receivedMessage);
if (!_.isEqual(receivedMessage.Type, messageType.USERPROFILES_USER_UPDATED)) {
return;
}
//Message received and locked
callback(receivedMessage);
serviceBus.deleteMessage(lockedMessage, function (deleteError) {
if (!deleteError) {
// Message deleted
console.log('message has been deleted.');
}
});
}
catch (error) {
console.log('Start debugging');
console.log(lockedMessage.body);
}
当我收到一条消息时,它的编码很奇怪,JSON.parse 引发异常。
lockedMessage 输出为:
{ body: '@\fbase64Binary\b3http://schemas.microsoft.com/2003/10/Serialization/�s\u0002{"Type":"SomeEvent"�\u0001}',
brokerProperties:
{ DeliveryCount: 9,
EnqueuedSequenceNumber: 0,
EnqueuedTimeUtc: 'Thu, 16 Nov 2017 23:50:16 GMT',
LockToken: '6e3e311f-0fe9-4366-844d-18046fd000db',
LockedUntilUtc: 'Fri, 17 Nov 2017 00:10:46 GMT',
MessageId: 'nil',
PartitionKey: '1d84084f-65af-4a33-bb30-62d97d85557d',
SequenceNumber: 61643019899633670,
SessionId: '1d84084f-65af-4a33-bb30-62d97d85557d',
State: 'Active',
TimeToLive: 1566804.069 },
location: '',
contentType: 'application/xml; charset=utf-8',
customProperties: { 'strict-transport-security': NaN, connection: NaN } }
消息来自 .NET Core 服务,该服务使用以下代码发送:
var payload = JsonConvert.SerializeObject(SomeEvent);
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
topicClient.SendAsync(serviceBusMessage).Wait();
为什么 Node.js 无法解析邮件?另一个 .NET 应用程序可以毫无问题地接收相同的消息。
为避免这种情况,您需要在从 .NET Core 服务发送消息时将 ContentType
设置为 text/plain
。所以它应该是这样的:
var payload = JsonConvert.SerializeObject(SomeEvent);
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload))
{
ContentType = "text/plain"
};
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
topicClient.SendAsync(serviceBusMessage).Wait();
在此 article 中,他们解释了 .NET 的问题和解决方案。
更新:
经过一番探索,当我使用 .NET Core 或 .NET 通过标准库 Microsoft.Azure.ServiceBus
发送消息时,无论是否指定 ContentType
都不会发生这种情况。
这是我发送消息的 C# 代码:
class Program
{
static void Main(string[] args)
{
string connectionString = "Endpoint=sb://...";
var client = new TopicClient(connectionString, "MyTopic");
var payload = JsonConvert.SerializeObject(new DemoMessage() { Title = $"hello core!!! {DateTime.Now}" });
var serviceBusMessage = new Message(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
client.SendAsync(serviceBusMessage).Wait();
}
private class DemoMessage
{
public DemoMessage()
{
}
public string Title { get; set; }
}
}
这是我的 Node.js 接收消息的代码:
var azure = require('azure');
var serviceBusService = azure.createServiceBusService("Endpoint=sb://...");
serviceBusService.receiveSubscriptionMessage('MyTopic', 'sub1', { isPeekLock: true }, function(error, lockedMessage) {
if(!error) {
console.log(lockedMessage);
serviceBusService.deleteMessage(lockedMessage, function (deleteError){
if(!deleteError){
// Message deleted
console.log('message has been deleted.');
}
})
}
});
lockedMessage
输出为:
这仅在我使用 .NET 和 SDK WindowsAzure.ServiceBus
时发生,代码如下:
class Program
{
static void Main(string[] args)
{
string connectionString = "Endpoint=sb://...";
var client = TopicClient.CreateFromConnectionString(connectionString, "MyTopic");
var payload = JsonConvert.SerializeObject(new DemoMessage() { Title = $"hello core!!! {DateTime.Now}" });
var serviceBusMessage = new BrokeredMessage(Encoding.UTF8.GetBytes(payload));
serviceBusMessage.SessionId = Guid.NewGuid().ToString("D");
client.Send(serviceBusMessage);
}
private class DemoMessage
{
public DemoMessage()
{
}
public string Title { get; set; }
}
}
现在,lockedMessage
输出是:
所以,我认为您收到的消息是从另一个 .NET 客户端发送的,我建议您在 Node.js.
中测试之前清除主题中的所有消息我也运行关注这个问题。如果您使用的是流分析,则其兼容性级别可能是导致此问题的原因。流分析兼容级别 1.0 使用 XML 序列化程序生成您看到的 XML 标记。兼容级别 1.1 "fixes" 这个问题。
在这里查看我之前的回答: