javascript - 无法在 Node.js 应用程序中解析从 Azure 服务总线接收到的 JSON 消息

标签 javascript json node.js azure azureservicebus

这是我的 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 输出为:

enter image description here


只有当我使用 .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 输出为:

enter image description here

因此,我认为您收到的消息是从另一个 .NET 客户端发送的,我建议您在 Node.js 中测试之前清除该主题中的所有消息。

关于javascript - 无法在 Node.js 应用程序中解析从 Azure 服务总线接收到的 JSON 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47341567/

相关文章:

c#,asp.net,压缩文件需要很长时间并且浏览器变得无响应

java - 使用 Retrofit 和 Gson 以及返回动态顶级 JSON 的 api

javascript - NodeJS 使用 Puppeteer 处理弹出窗口

javascript - 使用 Javascript 复制选定的文本?

javascript - 以编程方式删除焦点?

javascript - JavaScript 中包含转义序列的正则表达式

android - Firebase 云消息传递 - 响应 JSON 中的 "success"和 "failure"

ios - 遍历来自 Alamofire 的 JSON 响应

node.js - 如何在 Node.js 中强制同步?

javascript - Sails.js 查找哪里报错