IoT Hub(Java)를 사용하여 클라우드-디바이스 메시지 보내기

Azure IoT Hub는 수백만 개의 디바이스와 솔루션 백 엔드 간에 안정적이고 안전한 양방향 통신이 가능하도록 지원하는 완전히 관리되는 서비스입니다.

이 문서는 다음을 수행하는 방법을 보여줍니다.

  • IoT Hub를 통해 C2D(클라우드-디바이스) 메시지를 솔루션 백 엔드에서 단일 디바이스로 보냅니다.

  • 디바이스에서 클라우드-디바이스 메시지를 받습니다.

  • IoT Hub에서 디바이스로 보낸 메시지에 대해 솔루션 백 엔드에서 전송 확인(피드백)을 요청합니다.

참고 항목

이 문서에서 설명하는 기능은 IoT Hub의 표준 계층에서만 사용할 수 있습니다. 기본 및 표준/무료 IoT Hub 계층에 대한 자세한 내용은 솔루션에 적합한 IoT Hub 계층 선택을 참조하세요.

이 문서를 마치면 다음과 같은 두 개의 Java 콘솔 앱을 실행합니다.

  • HandleMessages: IoT Hub에 연결하고 클라우드-디바이스 메시지를 수신하는 Java용 Microsoft Azure IoT SDK에 포함된 샘플 디바이스 앱입니다.

  • SendCloudToDevice: IoT Hub를 통해 클라우드-디바이스 메시지를 디바이스 앱에 보낸 다음, 전송 확인을 받습니다.

참고 항목

IoT Hub는 Azure IoT 디바이스 SDK를 통해 다양한 디바이스 플랫폼 및 언어(C, Java, Python 및 JavaScript)에 대한 SDK 지원을 제공합니다.

클라우드-디바이스 메시지에 대해 자세히 알아보려면 IoT 허브에서 클라우드-디바이스 메시지 보내기를 참조하세요.

필수 구성 요소

  • Azure 구독 Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.

  • Azure 구독의 IoT Hub 아직 허브가 없는 경우 IoT Hub 만들기의 단계를 따를 수 있습니다.

  • IoT Hub에 등록된 디바이스. 아직 디바이스를 등록하지 않은 경우 Azure Portal에 등록합니다.

  • 이 문서에서는 Java용 Azure IoT SDK의 샘플 코드를 사용합니다.

    • GitHub에서 개발 머신으로 SDK 리포지토리를 다운로드하거나 복제합니다.
    • 개발 머신에 Java SE Development Kit 8이 설치되어 있는지 확인합니다. JDK 8용 다운로드를 가져오려면 장기 지원에서 Java 8을 선택해야 합니다.
  • Maven 3

  • 방화벽에서 포트 8883이 열려 있는지 확인합니다. 이 문서의 디바이스 샘플은 포트 8883을 통해 통신하는 MQTT 프로토콜을 사용합니다. 이 포트는 일부 회사 및 교육용 네트워크 환경에서 차단될 수 있습니다. 이 문제를 해결하는 자세한 내용과 방법은 IoT Hub에 연결(MQTT)을 참조하세요.

디바이스 연결 문자열 가져오기

이 문서에서는 IoT Hub를 통해 전송된 클라우드-디바이스 메시지를 수신하는 디바이스를 시뮬레이션하는 샘플 앱을 실행합니다. Java용 Microsoft Azure IoT SDK에 포함된 HandleMessages 샘플 앱은 IoT Hub에 연결하고 시뮬레이션된 디바이스 역할을 합니다. 이 샘플에서는 IoT Hub에 등록된 디바이스의 기본 연결 문자열을 사용합니다.

IoT Hub에 등록된 디바이스에 대한 기본 연결 문자열을 가져오려면 다음 단계를 수행합니다.

  1. Azure Portal에서 리소스 그룹을 선택합니다. 허브가 있는 리소스 그룹을 선택한 다음, 리소스 목록에서 허브를 선택합니다.

  2. IoT Hub의 왼쪽 창에 있는 디바이스 관리 에서 디바이스를 선택합니다.

  3. 디바이스 목록에서 적절한 디바이스를 선택합니다.

  4. 기본 연결 문자열을 복사하고 값을 저장합니다.

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

디바이스 앱에서 메시지 수신

이 섹션에서는 HandleMessages 샘플 디바이스 앱을 실행하여 IoT Hub를 통해 전송된 C2D 메시지를 받습니다. 새 명령 프롬프트를 열고 Azure IoT Java SDK를 확장한 폴더에서 azure-iot-sdk-java\iothub\device\iot-device-samples\handle-messages 폴더로 이동합니다. 다음 명령을 실행하여 {Your device connection string} 자리 표시자 값을 IoT Hub의 등록된 디바이스에서 복사한 디바이스 연결 문자열로 바꿉니다.

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

다음은 성공적으로 시작되고 IoT Hub에 연결한 후 샘플 디바이스 앱에서 가져온 출력입니다.

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 Hub에 전달됩니다. 디바이스는 사용 중인 프로토콜에 관계없이 처리가 성공적으로 완료되면 이 값을 반환해야 합니다.

AMQP 및 HTTPS를 사용하지만 MQTT를 사용하지 않는 경우에는 디바이스가 다음을 수행할 수도 있습니다.

  • 메시지 중단 - IoT Hub가 나중에 사용하기 위해 디바이스 큐에 메시지를 보관합니다.
  • 메시지 거부 - 디바이스 큐에서 메시지가 영구적으로 제거됩니다.

디바이스에서 메시지를 완료, 중단 또는 거부할 수 없도록 하는 문제가 발생할 경우 IoT Hub는 정해진 시간 제한 기간이 지나면 메시지를 다시 배달하도록 큐에 넣습니다. 이런 이유로 디바이스 앱의 메시지 처리 논리는 idempotent이므로 같은 메시지를 여러 번 수신해도 동일한 결과가 생성됩니다.

클라우드-디바이스 메시지 수명 주기 및 IoT Hub가 클라우드-디바이스 메시지를 처리하는 방법에 대한 자세한 내용은 IoT 허브에서 클라우드-디바이스 메시지 보내기를 참조하세요.

참고 항목

MQTT 또는 AMQP 대신 HTTPS를 전송으로 사용하는 경우 DeviceClient 인스턴스는 IoT Hub의 메시지를 자주(최소 25분 간격) 확인합니다. MQTT, AMQP, HTTPS 지원 간 차이점에 대한 자세한 내용은 클라우드-디바이스 통신 지침통신 프로토콜 선택을 참조하세요.

IoT Hub 연결 문자열 가져오기

이 문서에서는 IoT Hub를 통해 클라우드-디바이스 메시지를 보내도록 백 엔드 서비스를 만듭니다. 클라우드-디바이스 메시지를 보내려면 서비스에 서비스 연결 권한이 있어야 합니다. 기본적으로 모든 IoT Hub는 이 사용 권한을 부여하는 service라는 공유 액세스 정책을 사용하여 만듭니다.

service 정책에 대한 IoT Hub 연결 문자열을 가져오려면 다음 단계를 수행합니다.

  1. Azure Portal에서 리소스 그룹을 선택합니다. 허브가 있는 리소스 그룹을 선택한 다음, 리소스 목록에서 허브를 선택합니다.

  2. IoT Hub의 왼쪽 창에서 공유 액세스 정책을 선택합니다.

  3. 정책 목록에서 ervice 정책을 선택합니다.

  4. 기본 연결 문자열을 복사하고 값을 저장합니다.

Screenshot that shows how to retrieve the connection string from your IoT Hub in the Azure portal.

IoT Hub 공유 액세스 정책 및 사용 권한에 대한 자세한 내용은 액세스 제어 및 권한을 참조하세요.

클라우드-디바이스 메시지 보내기

이 섹션에서는 클라우드-디바이스 메시지를 시뮬레이트된 디바이스 앱으로 보내는 Java 콘솔 응용 프로그램을 만듭니다. 디바이스의 디바이스 ID 및 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 파일을 열고 종속성 노드에 다음 종속성을 추가합니다. 의존성을 추가하면 IoT Hub 서비스와 통신하기 위해 애플리케이션에서 iothub-java-service-client 패키지를 사용할 수 있습니다.

    <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 hub에 연결하고 디바이스에 메시지를 보낸 다음 디바이스가 메시지를 수신하고 처리했다는 승인을 기다립니다.

    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 Hub의 등록된 디바이스에서 복사한 디바이스 연결 문자열로 바꿉니다. 이 단계에서는 IoT Hub에 원격 분석을 보내고 허브에서 보낸 클라우드-디바이스 메시지를 수신 대기하는 샘플 디바이스 앱을 시작합니다.

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

    Screenshot of the sample device app running in a console window.

  2. send-c2d-messages 폴더의 명령 프롬프트에서 다음 명령을 실행하여 클라우드-디바이스 메시지를 보내고 피드백 승인을 대기합니다.

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

    Screenshot of the sample service app running in a console window.

다음 단계

문서에서는 클라우드-디바이스 메시지를 보내고 받는 방법을 알아보았습니다.