事件发射器循环在节点红色功能中不起作用

时间:2017-03-22 05:43:21

标签: node.js node-red azure-iot-hub

我正在尝试使用node-red函数来使用AMQP读取Azure IoT Hub消息。我已经导入了azure-iothub模块。

下面的代码连接ok,getFeedbackReceiver返回一个AmqpReceiver对象(我可以看到对象输出到debug选项卡),它充当事件发射器。但是,发射器循环(msgReceiver.on)似乎没有运行。我甚至没有得到调试标签的空输出。

任何帮助表示感谢。

var azureamqp = global.get('azureamqp');

var iothub = azureamqp.Client.fromConnectionString(cnct);

try 
   {
         iothub.open(function()
         {
            node.send({type: "connection", payload: util.inspect(iothub)});
            node.status({ fill: "green", shape: "ring", text: "listening" }); 

            iothub.getFeedbackReceiver(function(err,msgReceiver)
                {
                    if (!err) 
                    {
                        node.send({type: "receiver", payload: util.inspect(msgReceiver)});
                        msgReceiver.on('message',function(message)
                            {
                                node.send({payload:message}); 
                            });                        
                    }
                    else
                    {
                        node.send({payload: err});
                    }
                });

            node.send({type: "streamend"}); 
            node.status({ fill: "red", shape: "ring", text: "disconnected" }); 
         });
   }
catch (err)
   {}

1 个答案:

答案 0 :(得分:1)

好的,我想我会看到正在发生的事情,这要归功于其他评论:首先,一些关于与IoT Hub进行消息传递的参考文档: https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messaging

有两种类型的消息通过IoT Hub发送,具体取决于它们的使用方向:

  • 云端到设备(C2D或命令):这些消息由云应用程序发送到一个或多个设备。它们存储在特定于设备的队列中,并在设备连接并开始侦听消息后立即传送到设备。一旦设备收到,设备可以选择将有关这些的反馈发送到IoT Hub。使用azure-iothub.Client.getFeedbackReceiver() API接收此反馈。我在答案的最后添加了更多关于此的内容。

  • 设备到云(D2C或遥测):这些消息由设备发送到云应用程序。这些消息存储在事件中心分区中,可以从这些分区中读取。使用Event Hubs SDK

  • 会发生这种情况

从问题和评论来看,您似乎正在尝试使用反馈API接收D2C消息(遥测) - 并且它无法正常工作,因为它并不意味着以这种方式工作。对于(糟糕的)API设计和缺乏文档,这是很好的反馈。

如何接收设备发送的消息:

github上的

This sample显示如何设置Event Hubs客户端,并可用于收听设备发送到IoT Hub的消息。This command in iothub-explorer也是一个简单的参考。

请在下面找到一个简单的例子:

'use strict';
var EventHubClient = require('azure-event-hubs').Client;
var Promise = require('bluebird');

var connectionString = '[IoT Hub Connection String]';
var client = EventHubClient.fromConnectionString(connectionString);
var receiveAfterTime = Date.now() - 5000;

var printError = function (err) {
  console.error(err.message);
};

var printEvent = function (ehEvent) {
  console.log('Event Received: ');
  console.log(JSON.stringify(ehEvent.body));
  console.log('');
};

client.open()
      .then(client.getPartitionIds.bind(client))
      .then(function (partitionIds) {
        return Promise.map(partitionIds, function (partitionId) {
          return client.createReceiver('$Default', partitionId, { 'startAfterTime' : receiveAfterTime}).then(function(receiver) {
            receiver.on('errorReceived', printError);
            receiver.on('message', printEvent);
          });
        });
      }).catch(printError);

关于该代码示例的更多信息:

基本上,Event Hubs客户端提供的AMQP连接可用于在事件中心的每个分区上打开接收器。分区用于存储设备发送的消息。每个分区都有自己的接收器,每个接收器都有一个message事件。因此,需要为每个分区打开一个接收器,以免从任何设备丢失任何消息。以下是关于事件中心和分区性质的更多信息:https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-what-is-event-hubs

有关C2D反馈的更多信息:

设备可以发送有关C2D消息的3种类型的反馈:

  • 接受(或完成)表示设备负责处理该消息,IoT Hub将从设备队列中删除此消息
  • 拒绝表示设备不需要此消息(可能是因为它的格式错误或不相关,这取决于您设备),IoT Hub将从队列中删除该消息。
  • 放弃意味着设备目前无法“关注”此消息,并希望IoT Hub稍后重新发送。邮件仍在队列中。

接受拒绝都将使用getFeedbackReceiver API进行观察,以及如果邮件从未收到或放弃过多则超时次。