使用 IoT 中心发送云到设备消息 (Node.js)Send cloud-to-device messages with IoT Hub (Node.js)

Azure IoT 中心是一项完全托管的服务,有助于在数百万台设备和单个解决方案后端之间实现安全可靠的双向通信。Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications between millions of devices and a solution back end. 从设备将遥测数据发送到 IoT 中心快速入门介绍了如何创建 IoT 中心、在其中预配设备标识,以及编写模拟设备应用来发送设备到云的消息。The Send telemetry from a device to an IoT hub quickstart shows how to create an IoT hub, provision a device identity in it, and code a simulated device app that sends device-to-cloud messages.

备注

本文介绍的功能仅在 IoT 中心的标准层中可用。The features described in this article are available only in the standard tier of IoT Hub. 有关基本和标准/免费 IoT 中心层的详细信息,请参阅选择合适的 IoT 中心层For more information about the basic and standard/free IoT Hub tiers, see Choose the right IoT Hub tier.

本教程在从设备将遥测数据发送到 IoT 中心的基础上编写。This tutorial builds on Send telemetry from a device to an IoT hub. 其中了说明了如何:It shows you how to:

  • 通过 IoT 中心,将云到设备的消息从解决方案后端发送到单个设备。From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
  • 在设备上接收云到设备的消息。Receive cloud-to-device messages on a device.
  • 通过解决方案后端,请求确认收到从 IoT 中心发送到设备的消息(反馈 )。From your solution back end, request delivery acknowledgment (feedback) for messages sent to a device from IoT Hub.

可以在 IoT 中心开发人员指南中找到有关云到设备消息的详细信息。You can find more information on cloud-to-device messages in the IoT Hub developer guide.

在本教程结束时,会运行两个 Node.js 控制台应用:At the end of this tutorial, you run two Node.js console apps:

  • SimulatedDevice从设备将遥测数据发送到 IoT 中心中创建的应用的修改版本),它连接到 IoT 中心并接收云到设备的消息。SimulatedDevice, a modified version of the app created in Send telemetry from a device to an IoT hub, which connects to your IoT hub and receives cloud-to-device messages.

  • SendCloudToDeviceMessage,它将云到设备消息通过 IoT 中心发送到模拟设备应用,然后接收其传送确认。SendCloudToDeviceMessage, which sends a cloud-to-device message to the simulated device app through IoT Hub, and then receives its delivery acknowledgment.

备注

IoT 中心通过 Azure IoT 设备 SDK 对许多设备平台和语言(包括 C、Java、Python 和 Javascript)提供 SDK 支持。IoT Hub has SDK support for many device platforms and languages (including C, Java, Python, and Javascript) through Azure IoT device SDKs. 有关如何将设备连接到本教程的代码以及通常如何连接到 Azure IoT 中心的分步说明,请参阅 Azure IoT 开发人员中心For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure IoT Hub, see the Azure IoT Developer Center.

先决条件Prerequisites

  • Node.js 版本 10.0.x 或更高版本。Node.js version 10.0.x or later. 准备开发环境介绍了如何在 Windows 或 Linux 上安装本教程所用的 Node.js。Prepare your development environment describes how to install Node.js for this tutorial on either Windows or Linux.

  • 有效的 Azure 帐户。An active Azure account. (如果没有帐户,只需几分钟即可创建一个试用帐户。)(If you don't have an account, you can create a trial account in just a couple of minutes.)

  • 确保已在防火墙中打开端口 8883。Make sure that port 8883 is open in your firewall. 本文中的设备示例使用 MQTT 协议,该协议通过端口 8883 进行通信。The device sample in this article uses MQTT protocol, which communicates over port 8883. 在某些公司和教育网络环境中,此端口可能被阻止。This port may be blocked in some corporate and educational network environments. 有关解决此问题的更多信息和方法,请参阅连接到 IoT 中心(MQTT)For more information and ways to work around this issue, see Connecting to IoT Hub (MQTT).

在模拟设备应用上接收消息Receive messages in the simulated device app

在本部分中,将修改在从设备将遥测数据发送到 IoT 中心中创建的模拟设备应用,以接收来自 IoT 中心的云到设备消息。In this section, you modify the simulated device app you created in Send telemetry from a device to an IoT hub to receive cloud-to-device messages from the IoT hub.

  1. 使用文本编辑器打开 SimulatedDevice.js 文件。Using a text editor, open the SimulatedDevice.js file. 此文件位于 iot-hub\Quickstarts\simulated-device 文件夹中,该文件夹位于在从设备将遥测数据发送到 IoT 中心快速入门中下载的 Node.js 示例代码的根文件夹中。This file is located in the iot-hub\Quickstarts\simulated-device folder off of the root folder of the Node.js sample code you downloaded in the Send telemetry from a device to an IoT hub quickstart.

  2. 将一个处理程序注册到设备客户端,用于接收从 IoT 中心发送的消息。Register a handler with the device client to receive messages sent from IoT Hub. 将对 client.on 的调用直接添加到创建设备客户端的行后面,如以下代码片段所示:Add the call to client.on just after the line that creates the device client as in the following snippet:

    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 中心它已处理消息。In this example, the device invokes the complete function to notify IoT Hub that it has processed the message. 如果使用 MQTT 传输,则对 complete 的调用不是必需的,可以省略。The call to complete is not required if you are using MQTT transport and can be omitted. 对 HTTPS 和 AMQP 来说,它是必需的。It is required for HTTPS and AMQP.

    备注

    如果使用 HTTPS(而不使用 MQTT 或 AMQP)作为传输,则 DeviceClient 实例将不会频繁(频率低于每 25 分钟一次)检查 IoT 中心发来的消息。If you use HTTPS instead of MQTT or AMQP as the transport, the DeviceClient instance checks for messages from IoT Hub infrequently (less than every 25 minutes). 有关 MQTT、AMQP 和 HTTPS 支持之间的差异以及 IoT 中心限制的详细信息,请参阅 IoT 中心开发人员指南For more information about the differences between MQTT, AMQP and HTTPS support, and IoT Hub throttling, see the IoT Hub developer guide.

获取 IoT 中心连接字符串Get the IoT hub connection string

在本文中,你将创建一项后端服务,用于通过你在将遥测数据从设备发送到 IoT 中心中创建的 IoT 中心发送云到设备消息。In this article, you create a backend service to send cloud-to-device messages through the IoT hub you created in Send telemetry from a device to an IoT hub. 若要发送云到设备消息,服务需要“服务连接”权限。 To send cloud-to-device messages, your service needs the service connect permission. 默认情况下,每个 IoT 中心都使用名为 service 的共享访问策略创建,该策略授予此权限。By default, every IoT Hub is created with a shared access policy named service that grants this permission.

若要获取 service 策略的 IoT 中心连接字符串,请执行以下步骤:To get the IoT Hub connection string for the service policy, follow these steps:

  1. Azure 门户中,选择“资源组” 。In the Azure portal, select Resource groups. 选择中心所在的资源组,然后从资源列表中选择中心。Select the resource group where your hub is located, and then select your hub from the list of resources.

  2. 在 IoT 中心的左侧窗格中,选择“共享访问策略” 。On the left-side pane of your IoT hub, select Shared access policies.

  3. 从策略列表中选择“service” 策略。From the list of policies, select the service policy.

  4. 在“共享访问密钥” 下,选择“连接字符串 - 主密钥” 所对应的“复制”图标并保存该值。Under Shared access keys, select the copy icon for the Connection string -- primary key and save the value.

    显示如何检索连接字符串

有关 IoT 中心共享访问策略和权限的详细信息,请参阅访问控制和权限For more information about IoT Hub shared access policies and permissions, see Access control and permissions.

发送云到设备的消息Send a cloud-to-device message

在本部分中,会创建一个 Node.js 控制台应用,用于将云到设备的消息发送到模拟设备应用。In this section, you create a Node.js console app that sends cloud-to-device messages to the simulated device app. 需要在从设备将遥测数据发送到 IoT 中心快速入门中添加的设备的设备 ID。You need the device ID of the device you added in the Send telemetry from a device to an IoT hub quickstart. 还需要先前在获取 IoT 中心连接字符串中复制的 IoT 中心连接字符串。You also need the IoT hub connection string you copied previously in Get the IoT hub connection string.

  1. 创建名为 sendcloudtodevicemessage的空文件夹。Create an empty folder called sendcloudtodevicemessage. 在命令提示符处,使用以下命令在 sendcloudtodevicemessage 文件夹中创建一个 package.json 文件。In the sendcloudtodevicemessage folder, create a package.json file using the following command at your command prompt. 接受所有默认值:Accept all the defaults:

    npm init
    
  2. 在命令提示符处,运行以下命令在 sendcloudtodevicemessage 文件夹中安装 azure-iothub 包:At your command prompt in the sendcloudtodevicemessage folder, run the following command to install the azure-iothub package:

    npm install azure-iothub --save
    
  3. 通过文本编辑器,在 sendcloudtodevicemessage 文件夹中创建一个 SendCloudToDeviceMessage.js 文件。Using a text editor, create a SendCloudToDeviceMessage.js file in the sendcloudtodevicemessage folder.

  4. SendCloudToDeviceMessage.js 文件的开头添加以下 require 语句:Add the following require statements at the start of the SendCloudToDeviceMessage.js file:

    'use strict';
    
    var Client = require('azure-iothub').Client;
    var Message = require('azure-iot-common').Message;
    
  5. 将以下代码添加到 SendCloudToDeviceMessage.js 文件。Add the following code to SendCloudToDeviceMessage.js file. 将“{iot hub connection string}”和“{device id}”占位符值替换为之前记下的 IoT 中心连接字符串和设备 ID:Replace the "{iot hub connection string}" and "{device id}" placeholder values with the IoT hub connection string and device ID you noted previously:

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

    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. 添加以下函数,以便在控制台中列显送达反馈消息:Add the following function to print delivery feedback messages to the console:

    function receiveFeedback(err, receiver){
      receiver.on('message', function (msg) {
        console.log('Feedback message:')
        console.log(msg.getData().toString('utf-8'));
      });
    }
    
  8. 添加以下代码,以便将消息发送到设备并在设备确认收到云到设备的消息时处理反馈消息:Add the following code to send a message to your device and handle the feedback message when the device acknowledges the cloud-to-device message:

    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 文件。Save and close SendCloudToDeviceMessage.js file.

运行应用程序Run the applications

现在,已准备就绪,可以运行应用程序了。You are now ready to run the applications.

  1. simulated-device 文件夹的命令提示符下,运行以下命令将遥测发送到 IoT 中心,并侦听云到设备消息:At the command prompt in the simulated-device folder, run the following command to send telemetry to IoT Hub and to listen for cloud-to-device messages:

    node SimulatedDevice.js 
    

    运行模拟设备应用

  2. sendcloudtodevicemessage 文件夹的命令提示符下,运行以下命令发送云到设备消息,并等待确认反馈:At a command prompt in the sendcloudtodevicemessage folder, run the following command to send a cloud-to-device message and wait for the acknowledgment feedback:

    node SendCloudToDeviceMessage.js 
    

    运行应用以发送云到设备的命令

    备注

    为简单起见,本教程不实现任何重试策略。For simplicity, this tutorial does not implement any retry policy. 在生产代码中,应按文章 Transient Fault Handling(暂时性故障处理)中所述实施重试策略(例如指数性的回退)。In production code, you should implement retry policies (such as exponential backoff), as suggested in the article, Transient Fault Handling.

后续步骤Next steps

在本教程中,已学习如何发送和接收云到设备的消息。In this tutorial, you learned how to send and receive cloud-to-device messages.

若要了解有关使用 IoT 中心开发解决方案的详细信息,请参阅 IoT 中心开发人员指南To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.