이 문서에서는 디바이스가 MQTT 프로토콜을 사용하여 Azure IoT Hub와 통신하는 방법을 설명합니다. IoT Hub 디바이스 엔드포인트는 다음을 사용하여 디바이스 연결을 지원합니다.
- 포트 8883에서 MQTT v3.1.1
- 포트 443의 WebSocket을 통해 MQTT v3.1.1
참고
클라우드-디바이스 메시지, 디바이스 트윈스, 디바이스 관리 등 이 문서에 언급된 일부 기능은 IoT Hub의 표준 계층에서만 사용할 수 있습니다. 기본 및 표준/무료 IoT Hub 계층에 대한 자세한 내용은 솔루션에 맞는 IoT Hub 계층 및 크기 선택을 참조하세요.
TLS를 사용하여 IoT Hub와의 모든 디바이스 통신을 보호해야 합니다. 따라서 IoT Hub는 포트 1883을 통해 안전하지 않은 MQTT 연결을 지원하지 않습니다.
IoT Hub 및 Event Grid에서 MQTT 지원 비교
IoT Hub는 모든 기능을 갖춘 MQTT broker가 아니며 MQTT v3.1.1 표준에 지정된 모든 동작을 지원하지는 않습니다. 솔루션에 클라우드 호스팅 MQTT 브로커가 필요한 경우 Azure Event Grid 를 대신 사용합니다. Event Grid를 사용하면 게시-구독 메시징 모델을 사용하여 유연한 계층적 토픽에서 MQTT 클라이언트 간에 양방향 통신을 수행할 수 있습니다. 또한 추가 처리를 위해 MQTT 메시지를 다른 Azure 서비스 또는 사용자 지정 엔드포인트로 라우팅할 수 있습니다.
다음 표에는 두 서비스 간의 MQTT 지원 차이점이 요약되어 있습니다.
IoT Hub | Event Grid |
---|---|
디바이스와 클라우드 앱이 긴밀하게 결합된 클라이언트-서버 모델 | 게시자와 구독자를 분리하는 게시-구독 모델 |
MQTT v3.1.1에 대한 제한된 기능 지원 예정된 추가 기능 지원 없음 | 더 많은 기능 지원 및 업계 규정 준수가 계획된 MQTT v3.1.1 및 v5 프로토콜 지원 |
정적 미리 정의된 토픽 | 와일드카드가 지원되는 사용자 지정 계층적 토픽 |
클라우드-디바이스 브로드캐스트 또는 디바이스-디바이스 통신을 지원하지 않습니다. | 디바이스-클라우드, 높은 팬아웃 클라우드-디바이스 브로드캐스트 및 디바이스-디바이스 통신 패턴 지원 |
최대 메시지 크기는 256KB입니다. | 최대 메시지 크기는 512KB입니다. |
IoT Hub에 연결
디바이스는 다음 옵션을 통해 MQTT 프로토콜을 사용하여 IoT 허브에 연결할 수 있습니다.
- Azure IoT 디바이스 SDK
- MQTT 프로토콜을 직접 사용.
많은 회사 및 교육용 방화벽이 MQTT 포트(TCP 포트 8883)를 차단합니다. 방화벽에서 포트 8883을 열 수 없는 경우 WebSockets를 통해 MQTT를 사용합니다. WebSockets를 통해 MQTT는 거의 항상 열려 있는 포트 443을 통해 통신합니다. Azure IoT SDK를 사용하는 경우 MQTT 및 WebSocket을 통한 MQTT 프로토콜을 지정하는 방법을 알아보려면 디바이스 SDK 사용을 참조하세요.
디바이스 SDK 사용
MQTT 프로토콜을 지원하는 Azure IoT 디바이스 SDK 는 Java, Node.js, C, C# 및 Python에 사용할 수 있습니다. 디바이스 SDK는 선택한 인증 메커니즘을 사용하여 IoT 허브에 대한 연결을 설정합니다. MQTT 프로토콜을 사용하려면 클라이언트 프로토콜 매개 변수를 MQTT에 설정해야 합니다. 클라이언트 프로토콜 매개 변수에서 WebSocket을 통한 MQTT를 지정할 수도 있습니다. 기본적으로는 디바이스 SDK는 CleanSession 플래그가 0으로 설정된 IoT Hub에 연결되고 QoS 1을 사용하여 IoT Hub와 메시지를 교환합니다. 더 빠른 메시지 교환을 위해 QoS 0 을 구성할 수 있지만 배달이 보장되지 않으며 승인되지 않는다는 점에 유의해야 합니다. 이러한 이유로 QoS 0을 종종 “보내고 잊어버리기”라고 부릅니다.
디바이스가 IoT Hub에 연결되면 디바이스 SDK는 디바이스가 IoT Hub와 메시지를 교환할 수 있도록 하는 메서드를 제공합니다.
다음 표에는 지원되는 각 언어의 코드 샘플에 대한 링크가 있고, MQTT 또는 WebSocket을 통한 MQTT 프로토콜을 사용하여 IoT Hub에 대한 연결을 설정하는 데 사용할 매개 변수를 지정합니다.
언어 | MQTT 프로토콜 매개 변수 | WebSocket을 통한 MQTT 프로토콜 매개 변수 |
---|---|---|
Node.JS | azure-iot-device-mqtt.Mqtt | azure-iot-device-mqtt.MqttWs |
Java | IotHubClientProtocol.MQTT | IotHubClientProtocol.MQTT_WS |
C | MQTT_Protocol | MQTT_WebSocket_Protocol |
C# | TransportType.Mqtt | MQTT가 실패하는 경우 TransportType.Mqtt는 WebSocket을 통한 MQTT로 대체됩니다. WebSocket을 통한 MQTT만 지정하려면 TransportType.Mqtt_WebSocket_Only를 사용합니다. |
Python | 기본적으로 MQTT 사용 | 클라이언트를 만들려면 호출에 추가 websockets=True 합니다. |
다음 조각에서는 Azure IoT Node.js SDK를 사용할 때 WebSockets 프로토콜을 통해 MQTT를 지정하는 방법을 보여 줍니다.
var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').MqttWs;
var client = Client.fromConnectionString(deviceConnectionString, Protocol);
다음 조각에서는 Azure IoT Python SDK를 사용할 때 WebSockets 프로토콜을 통해 MQTT를 지정하는 방법을 보여 줍니다.
from azure.iot.device.aio import IoTHubDeviceClient
device_client = IoTHubDeviceClient.create_from_connection_string(deviceConnectionString, websockets=True)
중요한
이 문서에서는 공유 액세스 서명(대칭 키 인증이라고도 함)을 사용하여 디바이스를 연결하는 단계를 설명합니다. 이 인증 방법은 테스트와 평가에 편리하지만, X.509 인증서를 사용하여 디바이스를 인증하는 것이 더 안전한 방식입니다. 자세한 내용은 IoT 솔루션을 위한 보안 모범 사례 > 연결 보안을 참조하십시오.
기본 keep-alive 시간 제한
IoT Hub 연결에 대한 클라이언트 연결이 활성 상태로 유지되도록 하기 위해 서비스와 클라이언트는 정기적으로 서로 연결 유지 ping을 보냅니다. 디바이스 SDK 중 하나를 사용하는 경우 클라이언트는 다음 표에 정의된 간격으로 연결 유지 메시지를 보냅니다.
언어 | 기본 keep-alive 간격 | 구성 가능 |
---|---|---|
Node.js | 180초 | 아니요 |
Java | 230초 | 아니요 |
C | 240초 | 예 |
C# | 300초* | 예 |
Python | 60초 | 예 |
*C# SDK는 MQTT KeepAliveInSeconds 속성의 기본값을 300초로 정의합니다. 실제로 SDK는 연결 유지 기간 집합당 ping 요청을 4회 보냅니다. 즉, SDK는 75초마다 한 번씩 keep-alive ping을 보냅니다.
MQTT v3.1.1 사양에 따라 IoT Hub의 연결 유지 ping 간격은 클라이언트 연결 유지 값의 1.5배입니다. 그러나 IoT Hub는 최대 서버 쪽 시간 제한을 29.45분(1,767초)으로 제한합니다.
예를 들어 Java SDK를 사용하는 디바이스는 keep-alive ping을 전송한 다음 네트워크 연결이 해제됩니다. 230초 후에 디바이스는 오프라인 상태이기 때문에 keep-alive ping을 놓칩니다. 그러나 IoT Hub는 즉시 연결을 닫지 않습니다. 디바이스의 연결을 끊기 전에 또 다른 (230 * 1.5) - 230 = 115
초 동안 대기하고 404104 DeviceConnectionClosedRemotely 오류가 발생합니다.
설정할 수 있는 최대 클라이언트 keep-alive 값은 1767 / 1.5 = 1177
초입니다. 모든 트래픽은 keep-alive를 다시 설정합니다. 예를 들어 SAS(공유 액세스 서명) 토큰 새로 고침이 성공하면 연결 유지가 다시 설정됩니다.
AMQP에서 MQTT로 디바이스 애플리케이션 마이그레이션
디바이스 SDK를 사용하는 경우 AMQP 사용에서 MQTT로 전환하려면 클라이언트 초기화에서 프로토콜 매개 변수를 변경해야 합니다.
AMQP에서 MQTT로 변경하는 경우 다음 항목을 확인합니다.
AMQP는 많은 조건에 대한 오류를 반환하는 한편 MQTT는 연결을 종료합니다. 따라서 예외 처리 논리를 변경해야 할 수 있습니다.
MQTT는 클라우드-디바이스 메시지를 받을 때 거부 작업을 지원하지 않습니다. 백 엔드 애플리케이션이 디바이스 애플리케이션에서 응답을 받아야 하는 경우 직접 메서드를 사용하는 것이 좋습니다.
AMQP는 Python SDK에서 지원되지 않습니다.
디바이스에서 직접 MQTT 프로토콜 사용
디바이스에서 IoT 디바이스 SDK를 사용할 수 없는 경우에도 포트 8883에서 MQTT 프로토콜을 사용하여 공용 디바이스 엔드포인트에 연결할 수 있습니다.
중요
이 문서에서는 공유 액세스 서명(대칭 키 인증이라고도 함)을 사용하여 디바이스를 연결하는 단계를 설명합니다. 이 인증 방법은 테스트와 평가에 편리하지만, X.509 인증서를 사용하여 디바이스를 인증하는 것이 더 안전한 방식입니다. 자세한 내용은 IoT 솔루션을 위한 보안 모범 사례 > 연결 보안을 참조하세요.
CONNECT 패킷에서 디바이스는 다음 값을 사용해야 합니다.
ClientId 필드에 deviceId를 사용합니다.
Username 필드에
{iotHub-hostname}/{device-id}/?api-version=2021-04-12
를 사용합니다. 여기서{iotHub-hostname}
은 IoT 허브의 전체CName
입니다.예를 들어 IoT Hub의 이름이 contoso.azure-devices.net 디바이스 이름이 MyDevice01인 경우 사용자 이름 필드에는 다음이 포함됩니다.
contoso.azure-devices.net/MyDevice01/?api-version=2021-04-12
예기치 않은 동작을 방지하려면 필드에 api-version을 포함합니다.
암호 필드에는 SAS 토큰을 사용합니다. 다음 코드 조각은 SAS 토큰의 형식을 보여 줍니다.
SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}
참고
X.509 인증서 인증을 사용하는 경우 SAS 토큰 암호가 필요하지 않습니다. 자세한 내용은 자습서: 테스트를 위한 인증서 만들기 및 업로드 를 참조하고 TLS 구성 섹션의 코드 지침을 따릅니다.
SAS 토큰을 생성하는 방법에 대한 자세한 내용은 공유 액세스 서명을 사용하여 IoT Hub에 대한 액세스 제어의 SAS 토큰을 디바이스로 사용 섹션을 참조하세요.
Visual Studio Code용 Azure IoT Hub 확장 또는 CLI 확장 명령 az iot hub generate-sas-token을 사용하여 SAS 토큰을 생성할 수도 있습니다. 그런 다음, 테스트를 위해 SAS 토큰을 복사하여 사용자 고유의 코드에 붙여넣을 수 있습니다.
확장은 다음 구조를 사용하여 SAS 토큰을 생성합니다.
HostName={iotHub-hostname};DeviceId=javadevice;SharedAccessSignature=SharedAccessSignature sr={iotHub-hostname}%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802
이 토큰에서 MQTT를 사용하여 연결할 때 암호 필드에서와 같이 사용하는 부분은 다음과 같습니다.
SharedAccessSignature sr={iotHub-hostname}%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802
디바이스 애플리케이션은 CONNECT 패킷에 Will 메시지를 지정할 수 있습니다. 디바이스 애플리케이션은 devices/{device-id}/messages/events/
또는 devices/{device-id}/messages/events/{property-bag}
를 Will 토픽 이름으로 사용하여 전달될 Will 메시지를 텔레메트리 메시지로 정의해야 합니다. 이 경우 네트워크 연결이 닫혀 있지만 DISCONNECT 패킷이 이전에 디바이스에서 수신되지 않은 경우 IoT Hub는 CONNECT 패킷에 제공된 Will 메시지를 원격 분석 채널로 전송합니다. 원격 분석 채널은 기본 이벤트 엔드포인트 또는 IoT Hub 라우팅으로 정의되는 사용자 지정 엔드포인트일 수 있습니다. 메시지에는 Will 값이 할당된 iothub MessageType 속성이 지정됩니다.
모듈에서 직접 MQTT 프로토콜 사용
모듈 ID를 사용하여 MQTT를 통해 IoT Hub에 연결할 수도 있습니다. 이 방법은 디바이스로 연결하는 것과 유사하지만 다음 값을 사용해야 합니다.
클라이언트 ID를
{device-id}/{module-id}
로 설정합니다.사용자 이름 및 암호를 사용하여 인증하는 경우 사용자 이름을
<hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2021-04-12
.로 설정합니다. SAS를 사용하는 경우 모듈 ID와 연결된 SAS 토큰을 암호로 사용합니다.devices/{device-id}/modules/{module-id}/messages/events/
를 원격 분석 데이터 게시용 토픽으로 사용합니다.Will 항목으로 사용합니다
devices/{device-id}/modules/{module-id}/messages/events/
.devices/{device-id}/modules/{module-id}/#
를 메시지 수신용 토픽으로 사용합니다.쌍 GET 및 PATCH 항목은 모듈 및 디바이스에 대해 동일합니다.
쌍 상태 항목은 모듈 및 디바이스에 대해 동일합니다.
모듈에서 MQTT를 사용하는 방법에 대한 자세한 내용은 IoT Edge 허브 MQTT 엔드포인트를 참조하세요.
Azure IoT 디바이스 SDK 없이 MQTT를 사용하는 샘플
IoT MQTT 샘플 리포지토리에는 Azure 디바이스 SDK를 사용하지 않고 원격 분석 메시지를 보내고, 클라우드-디바이스 메시지를 받고, 디바이스 쌍을 사용하는 방법을 보여주는 C/C++, Python, CLI 샘플이 포함되어 있습니다.
C/C++ 샘플은 Eclipse Mosquitto 라이브러리를 사용하고, Python 샘플은 Eclipse Paho를 사용하며, CLI 샘플은 mosquitto_pub
를 사용합니다.
자세한 내용은 자습서 - MQTT를 사용하여 디바이스 SDK를 사용하지 않고 IoT 디바이스 클라이언트를 개발합니다.
TLS 구성
MQTT 프로토콜을 직접 사용하려면 클라이언트가 TLS 1.2를 통해 연결해야 합니다. 이 단계를 건너뛰려는 모든 시도는 연결 오류로 실패합니다.
TLS 연결을 설정하려면 Azure에서 사용하는 DigiCert Global Root G2 루트 인증서를 다운로드하고 참조해야 할 수 있습니다. 이 인증서에 대한 자세한 내용은 Digicert의 웹 사이트를 참조하세요.
다음 예제에서는 Paho MQTT 라이브러리의 Python 버전을 사용하여 이 구성을 구현하는 방법을 보여 줍니다.
먼저, 명령줄 환경에서 Paho 라이브러리를 설치합니다.
pip install paho-mqtt
그런 다음, Python 스크립트로 클라이언트를 구현합니다. 다음 코드 조각에서 자리 표시자를 바꾸세요.
<local path to digicert.cer>
은 DigiCert 루트 인증서가 포함된 로컬 파일의 경로입니다. C에 대한 Azure IoT SDK에서 certs.c의 인증서 정보를 복사하여 이 파일을 만들 수 있습니다.-----BEGIN CERTIFICATE-----
및-----END CERTIFICATE-----
줄을 포함하고 모든 줄의 시작과 끝에서"
표시를 제거한 다음, 모든 줄의 마지막에서\r\n
문자를 제거합니다.<device id from device registry>
IoT Hub에 추가된 디바이스의 ID입니다.<generated SAS token>
은 이 문서의 앞에서 설명한 디바이스에 대한 SAS 토큰입니다.<iot hub name>
은 IoT Hub의 이름입니다.
from paho.mqtt import client as mqtt
import ssl
path_to_root_cert = "<local path to digicert.cer file>"
device_id = "<device id from device registry>"
sas_token = "<generated SAS token>"
iot_hub_name = "<iot hub name>"
def on_connect(client, userdata, flags, rc):
print("Device connected with result code: " + str(rc))
def on_disconnect(client, userdata, rc):
print("Device disconnected with result code: " + str(rc))
def on_publish(client, userdata, mid):
print("Device sent message")
client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
device_id + "/?api-version=2021-04-12", password=sas_token)
client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None,
cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_insecure_set(False)
client.connect(iot_hub_name+".azure-devices.net", port=8883)
client.publish("devices/" + device_id + "/messages/events/", '{"id":123}', qos=1)
client.loop_forever()
디바이스 인증서를 사용하여 인증하려면 이전 코드 조각을 다음 코드 조각에 지정된 변경 내용으로 업데이트합니다. 인증서 기반 인증을 준비하는 방법에 대한 자세한 내용은 X.509 인증서를 사용하여 ID 인증의 X.509 CA 인증서 가져오기 섹션을 참조 하세요.
# Create the client as before
# ...
# Set the username but not the password on your client
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
device_id + "/?api-version=2021-04-12", password=None)
# Set the certificate and key paths on your client
cert_file = "<local path to your certificate file>"
key_file = "<local path to your device key file>"
client.tls_set(ca_certs=path_to_root_cert, certfile=cert_file, keyfile=key_file,
cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
# Connect as before
client.connect(iot_hub_name+".azure-devices.net", port=8883)
디바이스-클라우드 메시지 보내기
디바이스 연결 후 devices/{device-id}/messages/events/
또는 devices/{device-id}/messages/events/{property-bag}
를 토픽 이름으로 사용하여 IoT Hub에 메시지를 보낼 수 있습니다. {property-bag}
요소를 사용하면 디바이스에서 URL로 인코딩된 형식의 다른 속성이 있는 메시지를 보낼 수 있습니다. 예시:
RFC 2396-encoded(<PropertyName1>)=RFC 2396-encoded(<PropertyValue1>)&RFC 2396-encoded(<PropertyName2>)=RFC 2396-encoded(<PropertyValue2>)…
이 {property_bag}
요소는 HTTPS 프로토콜의 쿼리 문자열과 동일한 인코딩을 사용합니다.
D2C 메시지를 Azure Storage 계정으로 라우팅하고 JSON 인코딩을 사용하려는 경우, {property_bag}
에서 언급된 이전 참고 사항의 일부로 $.ct=application%2Fjson&$.ce=utf-8
을(를) 포함하여 콘텐츠 형식과 콘텐츠 인코딩 정보를 지정해야 합니다.
참고
이러한 특성의 형식은 프로토콜에 따라 다릅니다. IoT Hub는 이러한 특성을 해당 시스템 속성으로 변환합니다. 자세한 내용은 IoT Hub 메시지 라우팅 쿼리 구문의 시스템 속성 섹션을 참조하세요.
다음 목록에서는 IoT Hub MQTT 구현 관련 동작을 요약합니다.
IoT Hub에서는 QoS 2 메시지를 지원하지 않습니다. 디바이스 애플리케이션이 QoS 2를 사용하여 메시지를 게시하는 경우 IoT Hub는 네트워크 연결을 닫습니다.
IoT Hub는
Retain
메시지를 보관하지 않습니다. 디바이스에서 RETAIN 플래그가 1로 설정된 메시지를 보내는 경우 IoT Hub는 mqtt-retain 애플리케이션 속성을 메시지에 추가합니다. 이 경우 IoT Hub는 보존된 메시지를 유지하는 대신 백 엔드 애플리케이션에 전달합니다.IoT Hub는 디바이스 당 하나의 활성 MQTT 연결만을 지원합니다. 동일한 디바이스 ID를 대신하여 새 MQTT 연결을 사용하면 IoT Hub가 기존 연결을 삭제하고 ConnectionForcefullyClosedOnNewConnection 400027 IoT Hub 로그에 기록합니다.
메시지 본문을 기반으로 메시지를 라우팅하려면 먼저 MQTT 토픽의 끝에 속성을
ct
추가하고 다음 예제와 같이 해당 값을application/json;charset=utf-8
설정합니다. 메시지 속성 또는 메시지 본문에 따라 메시지를 라우팅하는 방법에 대한 자세한 내용은 IoT Hub 메시지 라우팅 쿼리 구문 설명서를 참조하세요.devices/{device-id}/messages/events/$.ct=application%2Fjson%3Bcharset%3Dutf-8
자세한 내용은 IoT Hub를 사용하여 메시지 보내기 및 받기를 참조하세요.
클라우드로부터 장치로 메시지 받기
IoT Hub에서 메시지를 수신하려면 디바이스는 devices/{device-id}/messages/devicebound/#
을 토픽 필터로 사용하여 구독해야 합니다. 토픽 필터의 다중 수준 와일드카드 #
를 사용하면 디바이스가 토픽 이름에 더 많은 속성을 받을 수 있습니다. IoT Hub는 하위 토픽을 필터링하기 위해 #
또는 ?
와일드카드를 사용하는 것을 허용하지 않습니다. IoT Hub는 범용 게시-구독 메시징 브로커가 아니며 문서화된 토픽 이름 및 토픽 필터만 지원합니다. 디바이스는 한 번에 5개 토픽만 구독할 수 있습니다.
디바이스는 토픽 필터로 표시되는 devices/{device-id}/messages/devicebound/#
디바이스별 엔드포인트를 성공적으로 구독할 때까지 IoT Hub에서 메시지를 수신하지 않습니다. 구독이 설정되면 디바이스는 구독 시간 이후에 전송된 클라우드-디바이스 메시지를 받습니다. 디바이스가 CleanSession 플래그가 0으로 설정되어 연결되면 다양한 세션 간에 구독이 유지됩니다. 이 경우 다음 번에 디바이스가 CleanSession 0으로 연결될 때, 연결되지 않은 동안 보내진 미해결 메시지를 수신하게 됩니다. 디바이스에서 1로 설정된 CleanSession 플래그를 사용하는 경우 해당 디바이스 엔드포인트를 구독할 때까지 IoT Hub에서 어떤 메시지도 받지 않습니다.
IoT Hub는 토픽 이름을devices/{device-id}/messages/devicebound/
하거나 devices/{device-id}/messages/devicebound/{property-bag}
메시지 속성이 있는 경우 메시지를 배달합니다. {property-bag}
에는 메시지 속성의 URL 인코딩된 키/값 쌍이 있습니다. 애플리케이션 속성 및 사용자 설정 가능 시스템 속성(예: messageId 또는 correlationId)만 속성 모음에 포함됩니다. 시스템 속성 이름에는 접두사 $가 있으며, 애플리케이션 속성은 접두사가 없는 원래 속성 이름을 사용합니다. 속성 모음의 형식에 대한 자세한 내용은 디바이스-클라우드 메시지 보내기를 참조하세요.
클라우드-디바이스 메시지에서 속성 모음의 값은 다음 표와 같이 표시됩니다.
속성 값 | 표현 | 설명 |
---|---|---|
null |
key |
속성 모음에 키만 표시됩니다. |
빈 문자열 | key= |
키 뒤에 값이 없는 등호 기호가 있습니다. |
null이 아니며 비어 있지 않은 값 | key=value |
키 뒤에 등호와 값이 있습니다. |
다음 예제는 세 가지 애플리케이션 속성이 포함된 속성 모음인 값이 있는 null
, 빈 문자열("")인 prop2, "문자열" 값이 있는 prop3을 보여 줍니다.
/?prop1&prop2=&prop3=a%20string
디바이스 애플리케이션이 QoS 2를 사용하여 토픽을 구독하는 경우 IoT Hub는 SUBACK 패킷에서 최대 QoS 수준 1을 부여합니다. 그런 다음 IoT Hub는 메시지를 QoS 1을 사용하는 디바이스에 전달합니다.
디바이스 쌍 속성 검색
먼저 작업의 응답을 수신하기 위해 디바이스가 $iothub/twin/res/#
을 구독합니다. 그런 다음 $iothub/twin/GET/?$rid={request id}
에 채워진 값을 사용하여 빈 메시지를 항목에 보냅니다. 그러면 서비스는 요청과 동일한 $iothub/twin/res/{status}/?$rid={request-id}
를 사용하여 항목에 대한 디바이스 쌍 데이터를 포함하는 응답 메시지를 보냅니다.
요청 ID는 메시지 속성 값에 대한 유효한 값일 수 있으며, 상태는 정수로 확인됩니다. 자세한 내용은 IoT Hub를 사용하여 메시지 보내기 및 받기를 참조하세요.
응답 본문에는 다음 응답 예제와 같이 디바이스 쌍의 속성 섹션이 포함되어 있습니다.
{
"desired": {
"telemetrySendFrequency": "5m",
"$version": 12
},
"reported": {
"telemetrySendFrequency": "5m",
"batteryLevel": 55,
"$version": 123
}
}
가능한 상태 코드:
상태 | 설명 |
---|---|
200 | 성공 |
429 | 요청이 너무 많습니다(제한됨). 자세한 내용은 IoT Hub 할당량 및 제한을 참조하세요. |
5** | 서버 오류 |
자세한 내용은 IoT Hub의 디바이스 쌍 이해 및 사용을 참조하세요.
디바이스 트윈의 보고된 속성 업데이트
보고된 속성을 업데이트하기 위해 디바이스는 지정된 MQTT 토픽에 게시하여 IoT Hub에 요청을 발급합니다. IoT Hub는 요청을 처리한 후 다른 토픽에 게시하여 업데이트 작업의 성공 또는 실패 상태로 응답합니다. 디바이스는 쌍 업데이트 요청의 결과에 대한 알림을 받기 위해 이 항목을 구독할 수 있습니다. MQTT에서 이러한 유형의 요청/응답 상호 작용을 구현하기 위해 디바이스는 초기 업데이트 요청에서 요청 ID($rid
)를 제공합니다. 그러면 이 요청 ID가 IoT Hub의 응답에 포함되어 디바이스가 응답을 올바른 요청과 상호 연결할 수 있도록 합니다.
다음 시퀀스에서는 디바이스가 IoT Hub의 디바이스 쌍에서 보고된 속성을 업데이트하는 방법을 설명합니다.
디바이스는 먼저 토픽을 구독하여
$iothub/twin/res/#
IoT Hub에서 응답을 받을 수 있도록 합니다.디바이스는 디바이스 쌍 업데이트를 포함하는 메시지를
$iothub/twin/PATCH/properties/reported/?$rid={request-id}
항목에 전송합니다. 이 메시지는 요청 ID 값을 포함합니다.그러면 서비스에서는 항목
$iothub/twin/res/{status}/?$rid={request-id}
에 대해 보고된 속성 컬렉션의 새 ETag 값을 포함하는 응답 메시지를 보냅니다. 이 응답 메시지는 동일한 요청 ID를 요청으로 사용합니다.
요청 메시지 본문은 보고된 속성에 대한 새 값을 포함하는 JSON 문서를 포함합니다. JSON 문서의 각 멤버는 디바이스 쌍의 문서에 있는 해당 멤버를 업데이트하거나 추가합니다. null
로 설정된 구성원은 포함하는 개체에서 구성원을 삭제합니다. 예시:
{
"telemetrySendFrequency": "35m",
"batteryLevel": 60
}
가능한 상태 코드:
상태 | 설명 |
---|---|
204 | 성공(반환되는 콘텐츠 없음) |
400 | 잘못된 요청. 형식이 잘못된 JSON |
429 | IoT Hub 할당량 및 제한에 따라 요청이 너무 많습니다 (속도 제한 적용됨). |
5** | 서버 오류 |
다음 Python 코드 조각에서는 Paho MQTT 클라이언트를 사용하여 MQTT로 트윈 보고된 속성을 업데이트하는 프로세스를 보여줍니다.
from paho.mqtt import client as mqtt
# authenticate the client with IoT Hub (not shown here)
client.subscribe("$iothub/twin/res/#")
rid = "1"
twin_reported_property_patch = "{\"firmware_version\": \"v1.1\"}"
client.publish("$iothub/twin/PATCH/properties/reported/?$rid=" +
rid, twin_reported_property_patch, qos=0)
쌍 reported 속성 업데이트 프로세스가 성공하면 IoT Hub는 다음 항목에 메시지를 게시합니다. $iothub/twin/res/204/?$rid=1&$version=6
, 여기서 204
는 성공을 나타내는 상태 코드이고, $rid=1
은 코드에서 디바이스가 제공한 요청 ID에 해당하고, $version
은 업데이트 후 디바이스 쌍의 보고된 속성 섹션 버전에 해당합니다.
자세한 내용은 IoT Hub의 디바이스 쌍 이해 및 사용을 참조하세요.
원하는 속성 업데이트 알림 받기
디바이스가 연결되면 IoT Hub는 $iothub/twin/PATCH/properties/desired/?$version={new-version}
항목에 알림을 보내는데 여기에는 솔루션 백 엔드에 의해 수행된 업데이트 콘텐츠가 포함됩니다. 예시:
{
"telemetrySendFrequency": "5m",
"route": null,
"$version": 8
}
속성 업데이트의 경우 null
값은 JSON 개체 멤버가 삭제되고 있음을 의미합니다. 또한 $version
은 쌍에 포함된 원하는 속성 섹션의 새 버전을 나타냅니다.
중요한
IoT Hub는 디바이스가 연결된 경우에만 변경 알림을 생성하여 IoT Hub와 디바이스 애플리케이션 간에 원하는 속성을 동기화된 상태로 유지하기 위해 디바이스 다시 연결 흐름을 구현해야 합니다.
자세한 내용은 IoT Hub의 디바이스 쌍 이해 및 사용을 참조하세요.
직접 메서드에 응답
먼저 디바이스가 $iothub/methods/POST/#
에 가입합니다. IoT Hub는 $iothub/methods/POST/{method-name}/?$rid={request-id}
항목에 유효한 JSON 또는 빈 본문으로 메서드 요청을 보냅니다.
응답하기 위해 디바이스는 올바른 JSON 또는 빈 본문이 있는 메시지를 $iothub/methods/res/{status}/?$rid={request-id}
토픽에 보냅니다. 이 메시지에서 요청 ID는 요청 메시지의 것과 일치하고 상태는 정수여야 합니다.
자세한 내용은 IoT Hub의 직접 메서드 이해 및 호출을 참조하세요.
다음 단계
MQTT 사용에 대한 자세한 내용은 다음을 참조하세요.