使用 IoT 中心发送云到设备的消息 (Node.js)

Azure IoT 中心是一项完全托管的服务,有助于在数百万台设备和单个解决方案后端之间实现安全可靠的双向通信。

本文介绍如何:

  • 通过 IoT 中心,将云到设备的消息从解决方案后端发送到单个设备

  • 在设备上接收云到设备的消息

  • 从解决方案后端,请求送达确认,确认收到从 IoT 中心发送到设备的消息(反馈)

注意

本文所述的功能只能用于 IoT 中心的标准层。 有关 IoT 中心基本层和标准/免费层的详细信息,请参阅选择适合你的解决方案的 IoT 中心层

在本文结束时,会运行两个 Node.js 控制台应用:

  • SimulatedDevice:从设备将遥测数据发送到 IoT 中心中创建的应用的修改版本,它连接到 IoT 中心并接收云到设备的消息。

  • SendCloudToDevice:它通过 IoT 中心将云到设备消息发送到设备应用,然后接收其送达确认。

注意

IoT 中心通过 Azure IoT 设备 SDK 对许多设备平台和语言(C、Java、Python 和 JavaScript)提供 SDK 支持

若要详细了解云到设备的消息,请参阅从 IoT 中心发送云到设备的消息

先决条件

在模拟设备应用上接收消息

在本部分,修改设备应用,使其从 IoT 中心接收云到设备消息。

  1. 使用文本编辑器打开 SimulatedDevice.js 文件。 此文件位于在将遥测数据从设备发送到 IoT 中心快速入门中下载的 Node.js 示例代码的根文件夹的 iot-hub\Quickstarts\simulated-device 文件夹中。

  2. 向设备客户端注册处理程序,以接收从 IoT 中心发送的消息。 紧接在创建设备客户端的行之后添加对 client.on 的调用,如以下代码片段所示:

    var client = DeviceClient.fromConnectionString(connectionString, Mqtt);
    
    client.on('message', function (msg) {
      console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
      client.complete(msg, function (err) {
        if (err) {
          console.error('complete error: ' + err.toString());
        } else {
          console.log('complete sent');
        }
      });
    });
    

在本示例中,设备调用 complete 函数以通知 IoT 中心它已处理消息,并且可以安全地从设备队列中将其删除。 对 complete 的调用在使用 MQTT 传输时不需要,可以省略。 对 AMQP 和 HTTPS 来说,它是必需的。

使用 AMQP 和 HTTPS,但不使用 MQTT,该设备还可以:

  • 放弃消息,使 IoT 中心将消息保留在设备队列中供将来使用。
  • 拒绝消息,这会永久地从设备队列中删除该消息。

如果发生阻止设备完成、放弃或拒绝消息的情况,IoT 中心会在固定的超时期限过后再次对消息排队以进行传递。 因此,设备应用中的消息处理逻辑必须是幂等的,这样,多次接收相同的消息才会生成相同的结果。

若要获取有关云到设备消息生命周期以及 IoT 中心如何处理云到设备消息的详细信息,请参阅从 IoT 中心发送云到设备的消息

注意

如果使用 HTTPS(而不使用 MQTT 或 AMQP)作为传输,则 DeviceClient 实例不会频繁检查 IoT 中心发来的消息(频率最低为每 25 分钟一次)。 有关 MQTT、AMQP 和 HTTPS 支持之间的差异的详细信息,请参阅云到设备通信指南选择通信协议

获取 IoT 中心连接字符串

本文中,你将创建一个后端服务,用于通过 IoT 中心发送云到设备的消息。 若要发送云到设备消息,服务需要服务连接权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。

若要获取 service策略的 IoT 中心连接字符串,请执行以下步骤:

  1. Azure 门户中,选择“资源组”。 选择中心所在的资源组,然后从资源列表中选择中心。

  2. 在 IoT 中心的左侧窗格上,选择“共享访问策略”。

  3. 在策略列表中,选择“service”策略。

  4. 复制“主连接字符串”并保存该值。

Screenshot that shows how to retrieve the connection string from your IoT Hub in the Azure portal.

有关 IoT 中心共享访问策略和权限的详细信息,请参阅访问控制和权限

发送云到设备的消息

在本部分中,创建一个 Node.js 控制台应用程序,它将云到设备的消息发送到模拟设备应用程序。 需要设备的设备 ID 和 IoT 中心连接字符串。

  1. 创建名为 sendcloudtodevicemessage 的空文件夹。 在命令提示符处,使用以下命令在 sendcloudtodevicemessage 文件夹中创建一个 package.json 文件。 接受所有默认值:

    npm init
    
  2. 在命令提示符处,运行以下命令在 sendcloudtodevicemessage 文件夹中安装 azure iothub 包:

    npm install azure-iothub --save
    
  3. 通过文本编辑器,在 sendcloudtodevicemessage文件夹中创建一个 SendCloudToDeviceMessage.js 文件。

  4. SendCloudToDeviceMessage.js 文件的开头添加以下 require 语句:

    'use strict';
    
    var Client = require('azure-iothub').Client;
    var Message = require('azure-iot-common').Message;
    
  5. 将以下代码添加到 SendCloudToDeviceMessage.js 文件。 将“{iot hub connection string}”和“{device id}”占位符值替换为以前记下的 IoT 中心连接字符串和设备 ID:

    var connectionString = '{iot hub connection string}';
    var targetDevice = '{device id}';
    
    var serviceClient = Client.fromConnectionString(connectionString);
    
  6. 添加以下函数,以便在控制台中列显操作结果:

    function printResultFor(op) {
      return function printResult(err, res) {
        if (err) console.log(op + ' error: ' + err.toString());
        if (res) console.log(op + ' status: ' + res.constructor.name);
      };
    }
    
  7. 添加以下函数,以便在控制台中列显送达反馈消息:

    function receiveFeedback(err, receiver){
      receiver.on('message', function (msg) {
        console.log('Feedback message:')
        console.log(msg.getData().toString('utf-8'));
      });
    }
    
  8. 添加以下代码,以便在设备确认收到云到设备的消息时会消息发送到设备,并处理反馈消息:

    serviceClient.open(function (err) {
      if (err) {
        console.error('Could not connect: ' + err.message);
      } else {
        console.log('Service client connected');
        serviceClient.getFeedbackReceiver(receiveFeedback);
        var message = new Message('Cloud to device message.');
        message.ack = 'full';
        message.messageId = "My Message ID";
        console.log('Sending message: ' + message.getData());
        serviceClient.send(targetDevice, message, printResultFor('send'));
      }
    });
    
  9. 保存并关闭 SendCloudToDeviceMessage.js 文件。

运行应用程序

现在,已准备就绪,可以运行应用程序了。

  1. 在 simulated-device 文件夹中的命令提示符下,运行以下命令以开始将遥测发送到 IoT 中心,并侦听云到设备的消息:

    node SimulatedDevice.js
    

    Run the simulated device app

  2. sendcloudtodevicemessage 文件夹中的命令提示符下,运行以下命令发送云到设备的消息并等待确认反馈:

    node SendCloudToDeviceMessage.js
    

    Run the app to send the cloud-to-device command

    注意

    为简单起见,本文不实现任何重试策略。 在生产代码中,应按文章 Transient Fault Handling(暂时性故障处理)中所述实施重试策略(例如指数性的回退)。

后续步骤

本文已介绍了如何发送和接收云到设备的消息。