title | description | author | ms.service | services | ms.devlang | ms.topic | ms.date | ms.author |
---|---|---|---|---|---|---|---|---|
Cloud-to-device messages with Azure IoT Hub (Java) | Microsoft Docs |
How to send cloud-to-device messages to a device from an Azure IoT hub using the Azure IoT SDKs for Java. 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. |
dominicbetts |
iot-hub |
iot-hub |
java |
conceptual |
06/28/2017 |
dobett |
[!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 a Hub (Java) tutorial 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 (Java). It shows you how to do the following:
-
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 acknowledgement (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 Java console apps:
-
simulated-device, a modified version of the app created in Send telemetry from a device to a Hub (Java), which connects to your IoT hub and receives cloud-to-device messages.
-
send-c2d-messages, which sends a cloud-to-device message to the simulated device app through IoT Hub, and then receives its delivery acknowledgement.
Note
IoT Hub has SDK support for many device platforms and languages (including C, Java, 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.
To complete this tutorial, you need the following:
-
A complete working version of the Send telemetry from a device to a Hub (Java) or the Configure message routing with IoT Hub tutorial.
-
The latest Java SE Development Kit 8
-
An active Azure account. If you don't have an account, you can create a free account in just a couple of minutes.
In this section, you modify the simulated device app you created in Send telemetry from a device to a Hub (Java) to receive cloud-to-device messages from the IoT hub.
-
Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.
-
Add the following MessageCallback class as a nested class inside the App class. The execute method is invoked when the device receives a message from IoT Hub. In this example, the device always notifies the IoT hub that it has completed the message:
private static class AppMessageCallback implements MessageCallback { public IotHubMessageResult execute(Message msg, Object context) { System.out.println("Received message from hub: " + new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET)); return IotHubMessageResult.COMPLETE; } }
-
Modify the main method to create an AppMessageCallback instance and call the setMessageCallback method before it opens the client as follows:
client = new DeviceClient(connString, protocol); MessageCallback callback = new AppMessageCallback(); client.setMessageCallback(callback, null); client.open();
[!NOTE] 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). For more information about the differences between MQTT, AMQP and HTTPS support, and IoT Hub throttling, see the messaging section of the IoT Hub developer guide.
-
To build the simulated-device app using Maven, execute the following command at the command prompt in the simulated-device folder:
mvn clean package -DskipTests
In this section, you create a Java 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 a Hub (Java) quickstart. You also need the IoT Hub connection string for your hub that you can find in the Azure portal.
-
Create a Maven project called send-c2d-messages using the following command at your command prompt. Note this command is a single, long command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=send-c2d-messages -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
-
At your command prompt, navigate to the new send-c2d-messages folder.
-
Using a text editor, open the pom.xml file in the send-c2d-messages folder and add the following dependency to the dependencies node. Adding the dependency enables you to use the iothub-java-service-client package in your application to communicate with your IoT hub service:
<dependency> <groupId>com.microsoft.azure.sdk.iot</groupId> <artifactId>iot-service-client</artifactId> <version>1.7.23</version> </dependency>
[!NOTE] You can check for the latest version of iot-service-client using Maven search.
-
Save and close the pom.xml file.
-
Using a text editor, open the send-c2d-messages\src\main\java\com\mycompany\app\App.java file.
-
Add the following import statements to the file:
import com.microsoft.azure.sdk.iot.service.*; import java.io.IOException; import java.net.URISyntaxException;
-
Add the following class-level variables to the App class, replacing {yourhubconnectionstring} and {yourdeviceid} with the values your noted earlier:
private static final String connectionString = "{yourhubconnectionstring}"; private static final String deviceId = "{yourdeviceid}"; private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
-
Replace the main method with the following code. This code connects to your IoT hub, sends a message to your device, and then waits for an acknowledgment that the device received and processed the message:
public static void main(String[] args) throws IOException, URISyntaxException, Exception { ServiceClient serviceClient = ServiceClient.createFromConnectionString( connectionString, protocol); if (serviceClient != null) { serviceClient.open(); FeedbackReceiver feedbackReceiver = serviceClient .getFeedbackReceiver(); if (feedbackReceiver != null) feedbackReceiver.open(); Message messageToSend = new Message("Cloud to device message."); messageToSend.setDeliveryAcknowledgement(DeliveryAcknowledgement.Full); serviceClient.send(deviceId, messageToSend); System.out.println("Message sent to device"); FeedbackBatch feedbackBatch = feedbackReceiver.receive(10000); if (feedbackBatch != null) { System.out.println("Message feedback received, feedback time: " + feedbackBatch.getEnqueuedTimeUtc().toString()); } if (feedbackReceiver != null) feedbackReceiver.close(); serviceClient.close(); } }
[!NOTE] For simplicity's sake, 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.
-
To build the simulated-device app using Maven, execute the following command at the command prompt in the simulated-device folder:
mvn clean package -DskipTests
You are now ready to run the applications.
-
At a command prompt in the simulated-device folder, run the following command to begin sending telemetry to your IoT hub and to listen for cloud-to-device messages sent from your hub:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
-
At a command prompt in the send-c2d-messages folder, run the following command to send a cloud-to-device message and wait for a feedback acknowledgment:
mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
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 Solution Accelerators.
To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.