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

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

本文介绍如何:

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

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

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

注意

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

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

  • simple_sample_device:适用于 Node.js 的 Azure IoT SDK 随附的示例设备应用,可连接到 IoT 中心并接收云到设备的消息。

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

注意

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

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

先决条件

  • Azure 订阅。 如果没有 Azure 订阅,可在开始前创建一个试用帐户

  • Azure 订阅中的 IoT 中心。 如果还没有中心,则可以按照创建 IoT 中心中的步骤进行操作。

  • 在 IoT 中心注册的设备。 如果尚未注册设备,请在 Azure 门户中注册一个设备。

  • 本文使用适用于 Node.js 的 Azure IoT SDK 中的示例代码。

    • 将 SDK 存储库从 GitHub 下载或克隆到开发计算机。
    • 请确保已在你的开发计算机上安装 Node.js 10.0.x 或更高版本。 准备开发环境介绍了如何在 Windows 或 Linux 上安装本文所用的 Node.js。
  • 确保已在防火墙中打开端口 8883。 本文中的设备示例使用 MQTT 协议,该协议通过端口 8883 进行通信。 在某些公司和教育网络环境中,此端口可能被阻止。 有关解决此问题的更多信息和方法,请参阅连接到 IoT 中心(MQTT)

获取设备连接字符串

在本文中,你将运行一个模拟设备的示例应用,该应用接收通过 IoT 中心发送的云到设备的消息。 适用于 Node.js 的 Azure IoT SDK 随附的 simple_sample_device 示例应用可连接到 IoT 中心并充当模拟设备。 该示例使用 IoT 中心上已注册设备的主连接字符串。

若要获取注册到 IoT 中心的设备的主连接字符串,请执行以下步骤:

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

  2. 在 IoT 中心左侧窗格的“设备管理”下,选择“设备”。

  3. 从设备列表中,选择相应的设备。

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

    Screenshot that shows how to retrieve the primary connection string for a device registered to your IoT hub in the Azure portal.

在设备应用中接收消息

在本部分中,运行 simple_sample_device 示例设备应用以接收通过 IoT 中心发送的 C2D 消息。 打开新命令提示符,并导航到你在其中扩展 Azure IoT Node.js SDK 的文件夹下的 azure-iot-sdk-node\device\samples\javascript 文件夹。 运行以下命令,将 {Your device connection string} 占位符值替换为从 IoT 中心的已注册设备复制的设备连接字符串。

set IOTHUB_DEVICE_CONNECTION_STRING={Your device connection string}
node simple_sample_device.js

示例设备应用成功启动并连接到 IoT 中心后,其输出如下:

Client connected
Client connected
Client connected
Sending message: {"deviceId":"myFirstDevice","windSpeed":10.949952400617569,"temperature":26.0096515658525,"humidity":72.59398225838534}
Client connected
Client connected
send status: MessageEnqueued
Sending message: {"deviceId":"myFirstDevice","windSpeed":12.917649160180087,"temperature":27.336831253904613,"humidity":77.37300365434534}

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

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

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

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

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

注意

如果使用 HTTPS(而不使用 MQTT 或 AMQP)作为传输,客户端实例不会频繁检查 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 命令显示的每个提示处按 Enter 以接受该提示的默认值:

    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. azure-iot-sdk-node\device\samples\javascript 文件夹中的命令提示符中,运行以下命令以开始将遥测发送到 IoT 中心,并侦听云到设备的消息:

    node simple_sample_device.js
    

    Run the simulated device app

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

    node SendCloudToDeviceMessage.js
    

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

    注意

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

后续步骤

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