使用 IoT 中樞傳送雲端到裝置訊息 (Java)

Azure IoT 中樞是一項完全受控的服務,有助於讓數百萬個裝置和一個解決方案後端進行可靠且安全的雙向通訊。

本文示範如何:

  • 透過IoT 中樞,將雲端到裝置 (C2D) 訊息從解決方案後端傳送到單一裝置

  • 接收裝置上的雲端到裝置訊息

  • 從解決方案後端,要求確認收到從 IoT 中樞傳送到裝置的訊息 (意見反應)

注意

本文中所述的功能僅適用於 IoT 中樞的標準層。 如需基本和標準/免費IoT 中樞層的詳細資訊,請參閱為您的解決方案選擇正確的IoT 中樞層

在本文結尾處,您會執行兩個 JAVA 主控台應用程式:

  • HandleMessagesMicrosoft Azure IoT SDK for JAVA隨附的範例裝置應用程式,可連線到 IoT 中樞並接收雲端到裝置訊息。

  • SendCloudToDevice:透過 IoT 中樞,將雲端到裝置訊息傳送到裝置應用程式,然後接收其傳遞通知。

注意

IoT 中樞會透過 Azure IoT 裝置 SDK 為許多裝置平台和語言 (C、Java、Python 及 JavaScript) 提供 SDK 支援。

若要深入了解雲端到裝置訊息,請參閱從 IoT 中樞傳送雲端到裝置訊息

必要條件

  • Azure 訂用帳戶。 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

  • Azure 訂用帳戶中的 IoT 中樞。 如果您還沒有中樞,可遵循建立 IoT 中樞中的步驟。

  • 在 IoT 中樞內註冊的裝置。 如果您尚未註冊裝置,請在Azure 入口網站中註冊一個裝置。

  • 本文使用 適用于 JAVA 的 Azure IoT SDK範例程式碼。

  • Maven 3

  • 請確定您的防火牆已開啟連接埠 8883。 本文中的裝置範例會使用 MQTT 通訊協定,其會透過連接埠 8883 進行通訊。 某些公司和教育網路環境可能會封鎖此連接埠。 如需此問題的詳細資訊和解決方法,請參閱連線至 IoT 中樞 (MQTT)

取得裝置連接字串

在本文中,您會執行模擬裝置的範例應用程式,以接收透過您IoT 中樞傳送的雲端到裝置訊息。 Microsoft Azure IoT SDK for JAVA隨附的HandleMessages範例應用程式會連線到 IoT 中樞,並作為模擬裝置。 此範例會使用 IoT 中樞上已註冊裝置的主要連接字串。

若要取得註冊至 IoT 中樞之裝置的主要連接字串,請遵循下列步驟:

  1. Azure 入口網站中選取 [資源群組]。 選取中樞所在的資源群組,然後從資源清單選取中樞。

  2. 在 IoT 中樞的左側窗格的[裝置管理] 底下,選取 [裝置]。

  3. 從裝置清單中,選取適當的裝置。

  4. 複製 [主要連接字串] 並儲存該值。

    此螢幕擷取畫面顯示如何擷取Azure 入口網站中註冊至 IoT 中樞之裝置的主要連接字串。

在裝置應用程式中接收訊息

在本節中,執行 HandleMessages 範例裝置應用程式,以接收透過 IoT 中樞傳送的 C2D 訊息。 開啟新的命令提示字元,並在您展開 Azure IoT JAVA SDK 的資料夾下,流覽至 azure-iot-sdk-java\iothub\device-samples\handle-messages 資料夾。 執行下列命令,將 {Your device connection string} 預留位置值取代為您從 IoT 中樞的已註冊裝置複製的裝置連接字串。

mvn clean package -DskipTests
java -jar ./target/handle-messages-1.0.0-with-deps.jar "{Your device connection string}"

下列輸出是在成功啟動並聯機到 IoT 中樞之後,來自範例裝置應用程式:

5/22/2023 11:13:18 AM> Press Control+C at any time to quit the sample.
     
Starting...
Beginning setup.
Successfully read input parameters.
Using communication protocol MQTT.
2023-05-23 09:51:06,062 INFO (main) [com.microsoft.azure.sdk.iot.device.transport.ExponentialBackoffWithJitter] - NOTE: A new instance of ExponentialBackoffWithJitter has been created with the following properties. Retry Count: 2147483647, Min Backoff Interval: 100, Max Backoff Interval: 10000, Max Time Between Retries: 100, Fast Retry Enabled: true
2023-05-23 09:51:06,187 DEBUG (main) [com.microsoft.azure.sdk.iot.device.ClientConfiguration] - Device configured to use software based SAS authentication provider
2023-05-23 09:51:06,187 INFO (main) [com.microsoft.azure.sdk.iot.device.transport.ExponentialBackoffWithJitter] - NOTE: A new instance of ExponentialBackoffWithJitter has been created with the following properties. Retry Count: 2147483647, Min Backoff Interval: 100, Max Backoff Interval: 10000, Max Time Between Retries: 100, Fast Retry Enabled: true
2023-05-23 09:51:06,202 DEBUG (main) [com.microsoft.azure.sdk.iot.device.DeviceClient] - Initialized a DeviceClient instance using SDK version 2.1.5
Successfully created an IoT Hub client.
Successfully set message callback.
2023-05-23 09:51:06,205 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection] - Opening MQTT connection...
2023-05-23 09:51:06,218 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sending MQTT CONNECT packet...
2023-05-23 09:51:07,308 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sent MQTT CONNECT packet was acknowledged
2023-05-23 09:51:07,308 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sending MQTT SUBSCRIBE packet for topic devices/US60536-device/messages/devicebound/#
2023-05-23 09:51:07,388 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.Mqtt] - Sent MQTT SUBSCRIBE packet for topic devices/US60536-device/messages/devicebound/# was acknowledged
2023-05-23 09:51:07,388 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.mqtt.MqttIotHubConnection] - MQTT connection opened successfully
2023-05-23 09:51:07,388 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - The connection to the IoT Hub has been established
2023-05-23 09:51:07,404 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Updating transport status to new status CONNECTED with reason CONNECTION_OK
2023-05-23 09:51:07,404 DEBUG (main) [com.microsoft.azure.sdk.iot.device.DeviceIO] - Starting worker threads
2023-05-23 09:51:07,408 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Invoking connection status callbacks with new status details

CONNECTION STATUS UPDATE: CONNECTED
CONNECTION STATUS REASON: CONNECTION_OK
CONNECTION STATUS THROWABLE: null

The connection was successfully established. Can send messages.
2023-05-23 09:51:07,408 DEBUG (main) [com.microsoft.azure.sdk.iot.device.transport.IotHubTransport] - Client connection opened successfully
2023-05-23 09:51:07,408 INFO (main) [com.microsoft.azure.sdk.iot.device.DeviceClient] - Device client opened successfully
Opened connection to IoT Hub. Messages sent to this device will now be received.
Press any key to exit...

AppMessageCallback 類別中的 execute 方法會傳回 IotHubMessageResult.COMPLETE。 此狀態會通知IoT 中樞訊息已成功處理,而且可以從裝置佇列安全地移除訊息。 無論使用的通訊協定為何,裝置在處理順利完成時,應該傳回此值。

透過 AMQP 和 HTTPS,但不是透過 MQTT,裝置也可以:

  • 放棄訊息,這會使得 IoT 中樞將訊息保留在裝置佇列中以供未來使用。
  • 拒絕訊息,這會永久移除裝置佇列中的訊息。

如果發生導致裝置無法完成、放棄或拒絕訊息的情況,IoT 中樞在固定的逾時期間之後,會將訊息排入佇列以再次傳遞。 基於這個原因,裝置應用程式中的訊息處理邏輯必須是「等冪」,如此一來,多次接收相同訊息才會產生相同的結果。

如需雲端到裝置訊息生命週期及 IoT 中樞如何處理雲端到裝置訊息的詳細資訊,請參閱從 IoT 中樞傳送雲端到裝置訊息

注意

如果您使用 HTTPS 而不是使用 MQTT 或 AMQP 作為傳輸,則 DeviceClient 執行個體將不會經常 (至少每隔 25 分鐘) 檢查 IoT 中樞是否有訊息。 如需 MQTT、AMQP 和 HTTPS 支援之間差異的詳細資訊,請參閱雲端到裝置的通訊指引選擇通訊協定

取得 IoT 中樞連接字串

在本文中,您會建立後端服務,以透過您的 IoT 中樞傳送雲端到裝置訊息。 若要傳送雲端到裝置訊息,則服務需要服務連線權限。 根據預設,每個 IoT 中樞都是透過授與此權限且名為服務的共用存取原則所建立。

若要取得服務原則的 IoT 中樞連接字串,請遵循下列步驟:

  1. Azure 入口網站中選取 [資源群組]。 選取中樞所在的資源群組,然後從資源清單選取中樞。

  2. 在 IoT 中樞的左側窗格中,選取 [共用存取原則]。

  3. 從原則清單中,選取服務原則。

  4. 複製 [主要連接字串] 並儲存該值。

顯示如何從您在 Azure 入口網站中的 IoT 中樞擷取連接字串的螢幕擷取畫面。

如需 IoT 中樞共用存取原則和權限的詳細資訊,請參閱存取控制及權限

傳送雲端到裝置訊息

在本節中,您會建立 Java 主控台應用程式,以將雲端到裝置訊息傳送給模擬裝置應用程式。 您需要來自裝置的裝置識別碼和 IoT 中樞連接字串。

  1. 在命令提示字元中使用下列命令,建立名為 send-c2d-messages 的 Maven 專案。 注意,此命令是單一且非常長的命令:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=send-c2d-messages -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. 在命令提示字元中,瀏覽到新的 send-c2d-messages 資料夾。

  3. 使用文字編輯器,開啟 [send-c2d-messages] 資料夾中的 pom.xml 檔案,並將下列相依性新增到 [相依性] 節點。 新增相依性可讓您在應用程式中使用 iothub-java-service-client 套件與 IoT 中樞服務進行通訊:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-service-client</artifactId>
      <version>1.7.23</version>
    </dependency>
    

    注意

    您可以使用 Maven 搜尋來檢查最新版的 iot-service-client

  4. 儲存並關閉 pom.xml 檔案。

  5. 使用文字編輯器開啟 send-c2d-messages\src\main\java\com\mycompany\app\App.java 檔案。

  6. 在此檔案中新增下列 import 陳述式:

    import com.microsoft.azure.sdk.iot.service.*;
    import java.io.IOException;
    import java.net.URISyntaxException;
    
  7. 將下列類別層級變數新增至 App 類別,其中以稍早記下的值來取代 {yourhubconnectionstring}{yourdeviceid}

    private static final String connectionString = "{yourhubconnectionstring}";
    private static final String deviceId = "{yourdeviceid}";
    private static final IotHubServiceClientProtocol protocol =    
        IotHubServiceClientProtocol.AMQPS;
    
  8. 以下列程式碼取代 main 方法。 此程式碼會連線至 IoT 中樞,傳送訊息給您的裝置,然後等候裝置已接收並處理訊息的通知︰

    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();
      }
    }
    

    注意

    為了簡單起見,本文不會實作重試原則。 在實際執行環境程式碼中,您應該如暫時性錯誤處理一文所建議,實作重試原則 (例如指數輪詢)。

  9. 若要使用 Maven 建置 send-c2d-messages 應用程式,請在 simulated-device 資料夾中的命令提示字元執行下列命令:

    mvn clean package -DskipTests
    

執行應用程式

您現在已準備好執行應用程式。

  1. azure-iot-sdk-java\iothub\device\iot-device-samples\handle-messages 資料夾中的命令提示字元中,執行下列命令,將預留位置值取代 {Your device connection string} 為您從 IoT 中樞的已註冊裝置複製的裝置連接字串。 此步驟會啟動範例裝置應用程式,它會將遙測傳送至 IoT 中樞,並接聽從中樞傳送的雲端到裝置訊息:

    java -jar ./target/handle-messages-1.0.0-with-deps.jar "{Your device connection string}"
    

    在主控台視窗中執行的範例裝置應用程式螢幕擷取畫面。

  2. send-c2d-messages 資料夾中的命令提示字元中,執行下列命令來傳送雲端到裝置訊息,並等候意見反應通知:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    在主控台視窗中執行的範例服務應用程式螢幕擷取畫面。

後續步驟

在本文中,您已了解如何傳送和接收雲端到裝置的訊息。