title | description | author | manager | ms.author | ms.service | services | ms.devlang | ms.topic | ms.date | ms.custom | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Cloud-to-device messages with Azure IoT Hub (Node) | Microsoft Docs |
How to send cloud-to-device messages to a device from an Azure IoT hub using the Azure IoT SDKs for Node.js. You modify a simulated device app to receive cloud-to-device messages and modify a back-end app to send the cloud-to-device messages. |
wesmc7777 |
philmea |
wesmc |
iot-hub |
iot-hub |
javascript |
conceptual |
06/16/2017 |
|
[!INCLUDE iot-hub-selector-c2d]
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. 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.
[!INCLUDE iot-hub-basic]
This tutorial builds on Send telemetry from a device to an IoT hub. It shows you how to:
- 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.
- From your solution back end, request delivery acknowledgment (feedback) for messages sent to a device from IoT Hub.
You can find more information on cloud-to-device messages in the IoT Hub developer guide.
At the end of this tutorial, you run two Node.js console apps:
-
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, which sends a cloud-to-device message to the simulated device app through IoT Hub, and then receives its delivery acknowledgment.
Note
IoT Hub has SDK support for many device platforms and languages (including C, Java, Python, and Javascript) through Azure IoT device SDKs. 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.
-
Node.js version 10.0.x or later. Prepare your development environment describes how to install Node.js for this tutorial on either Windows or Linux.
-
An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)
-
Make sure that port 8883 is open in your firewall. 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. For more information and ways to work around this issue, see Connecting to IoT Hub (MQTT).
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.
-
Using a text editor, open the SimulatedDevice.js file. 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.
-
Register a handler with the device client to receive messages sent from IoT Hub. 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'); } }); });
In this example, the device invokes the complete function to notify IoT Hub that it has processed the message and that it can safely be removed from the device queue. The call to complete is not required if you are using MQTT transport and can be omitted. It is required for AMQP and HTTPS.
With AMQP and HTTPS, but not MQTT, the device can also:
- Abandon a message, which results in IoT Hub retaining the message in the device queue for future consumption.
- Reject a message, which which permanently removes the message from the device queue.
If something happens that prevents the device from completing, abandoning, or rejecting the message, IoT Hub will, after a fixed timeout period, queue the message for delivery again. For this reason, the message processing logic in the device app must be idempotent, so that receiving the same message multiple times produces the same result.
For more detailed information about how IoT Hub processes cloud-to-device messages, including details of the cloud-to-device message lifecycle, see Send cloud-to-device messages from an IoT hub.
Note
If you use HTTPS instead of MQTT or AMQP as the transport, the DeviceClient instance checks for messages from IoT Hub infrequently (a minimum of every 25 minutes). For more information about the differences between MQTT, AMQP, and HTTPS support, see Cloud-to-device communications guidance and Choose a communication protocol.
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. By default, every IoT Hub is created with a shared access policy named service that grants this permission.
[!INCLUDE iot-hub-include-find-service-connection-string]
In this section, you create a Node.js console app that sends cloud-to-device messages to the simulated device app. You need the device ID of the device you added in the Send telemetry from a device to an IoT hub quickstart. You also need the IoT hub connection string you copied previously in Get the IoT hub connection string.
-
Create an empty folder called sendcloudtodevicemessage. In the sendcloudtodevicemessage folder, create a package.json file using the following command at your command prompt. Accept all the defaults:
npm init
-
At your command prompt in the sendcloudtodevicemessage folder, run the following command to install the azure-iothub package:
npm install azure-iothub --save
-
Using a text editor, create a SendCloudToDeviceMessage.js file in the sendcloudtodevicemessage folder.
-
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;
-
Add the following code to SendCloudToDeviceMessage.js file. 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);
-
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); }; }
-
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')); }); }
-
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')); } });
-
Save and close SendCloudToDeviceMessage.js file.
You are now ready to run the applications.
-
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
-
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
[!NOTE] For simplicity, this tutorial does not implement any retry policy. In production code, you should implement retry policies (such as exponential backoff), as suggested in the article, Transient Fault Handling.
In this tutorial, you learned how to send and receive cloud-to-device messages.
To see examples of complete end-to-end solutions that use IoT Hub, see Azure IoT Remote Monitoring solution accelerator.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.