Kommunizieren mit einem IoT-Hub mithilfe des MQTT-Protokolls

In diesem Artikel wird beschrieben, wie Geräte unterstützte MQTT-Verhaltensweisen für die Kommunikation mit Azure IoT Hub verwenden können. IoT Hub ermöglicht Geräten die Kommunikation mit den IoT Hub-Geräteendpunkten mithilfe von:

  • MQTT v3.1.1 an TCP-Port 8883
  • MQTT v3.1.1 über WebSocket an TCP-Port 443

Hinweis

Einige der in diesem Artikel erwähnten Features (wie Cloud-zu-Gerät-Messaging, Gerätezwillinge und Geräteverwaltung) stehen nur im Standard-Tarif von IoT Hub zur Verfügung. Weitere Informationen zu den IoT Hub-Tarifen „Basic“ und „Standard/Free“ finden Sie unter Wählen des richtigen IoT Hub-Tarifs für Ihre Lösung.

Die gesamte Gerätekommunikation mit IoT Hub muss mithilfe von TLS/SSL gesichert werden. Deshalb unterstützt IoT Hub keine unsicheren Verbindungen über TCP-Port 1883.

Vergleichen der MQTT-Unterstützung in IoT Hub und Event Grid

IoT Hub ist kein MQTT-Broker mit vollem Funktionsumfang und unterstützt nicht alle im MQTT v3.1.1-Standard angegebenen Verhaltensweisen. Wenn Ihre Lösung MQTT benötigt, empfehlen wir die MQTT-Unterstützung in Azure Event Grid. Event Grid ermöglicht die bidirektionale Kommunikation zwischen MQTT-Clients auf flexiblen hierarchischen Themen mithilfe eines Pub-Sub-Messagingmodells. Außerdem können Sie MQTT-Nachrichten an Azure-Dienste oder benutzerdefinierte Endpunkte zur weiteren Verarbeitung weiterleiten.

In der folgenden Tabelle werden die Unterschiede des MQTT-Supports zwischen den beiden Diensten erläutert:

IoT Hub Event Grid
Client/Servermodell mit enger Kopplung zwischen Geräten und Cloud-Apps. Publish/Subscribe-Modell, das Herausgeber und Abonnenten entkoppelt.
Eingeschränkte Featureunterstützung für MQTT v3.1.1 und eingeschränkte Featureunterstützung für MQTT v5 in der Vorschau. Eine weitere Featureunterstützung ist nicht geplant. MQTT v3.1.1- und v5-Protokollunterstützung mit mehr Featureunterstützung und branchenspezifischer Compliance geplant.
Statische, vordefinierte Themen. Benutzerdefinierte hierarchische Themen mit Platzhalterunterstützung.
Keine Unterstützung für Cloud-zu-Gerät-Übertragungen und Geräte-zu-Gerät-Kommunikation. Unterstützt Gerät-zu-Cloud-, High-Fan-out-Cloud-zu-Gerät-Übertragungen und Gerät-zu-Gerät-Kommunikationsmuster.
Maximale Nachrichtengröße von 256 KB. Maximale Nachrichtengröße von 512 KB.

Herstellen einer Verbindung mit einem IoT Hub

Ein Gerät kann das MQTT-Protokoll zum Herstellen einer Verbindung mit einem IoT-Hub über die folgenden Optionen verwenden:

Der MQTT-Port (TCP-Port 8883) wird in vielen Netzwerken von Unternehmen und Bildungseinrichtungen blockiert. Wenn Sie Port 8883 in Ihrer Firewall nicht öffnen können, empfehlen wir, MQTT über WebSockets zu verwenden. MQTT über WebSockets kommuniziert über Port 443, der in Netzwerkumgebungen fast immer geöffnet ist. Informationen zum Angeben der Protokolle für MQTT und MQTT über WebSockets bei Verwendung der Azure IoT-SDKs finden Sie unter Verwenden der Geräte-SDKs.

Verwenden der Geräte-SDKs

Geräte-SDKs, die das MQTT-Protokoll unterstützen, stehen für Java, Node.js, C, C# und Python zur Verfügung. Die Geräte-SDKs verwenden den ausgewählten Authentifizierungsmechanismus zum Herstellen einer Verbindung mit einem IoT-Hub. Um das MQTT-Protokoll verwenden zu können, muss der Clientprotokollparameter auf MQTTfestgelegt werden. Sie können MQTT über WebSockets auch im Parameter für das Clientprotokoll angeben. Standardmäßig verbinden sich die SDKs von Geräten mit einem IoT Hub, indem das CleanSession-Flag auf 0 festgelegt und QoS 1 für den Nachrichtenaustausch mit dem IoT Hub verwendet wird. Es ist möglich, QoS 0 für einen schnelleren Nachrichtenaustausch zu konfigurieren, dabei sollten Sie jedoch beachten, dass die Übermittlung weder garantiert noch bestätigt wird. Aus diesem Grund wird QoS 0 oft als „Fire and Forget“ bezeichnet.

Wenn ein Gerät mit einem IoT Hub verbunden ist, werden mit den SDKs von Geräten Methoden bereitgestellt, die dem Gerät den Austausch von Nachrichten mit einem IoT Hub ermöglichen.

Die folgende Tabelle enthält Links zu Codebeispielen für jede unterstützte Sprache sowie die Parameter zum Herstellen einer Verbindung mit IoT Hub mithilfe der Protokolle für MQTT oder MQTT über WebSockets.

Sprache Parameter für das MQTT-Protokoll Parameter des Protokolls für MQTT über WebSockets
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 Wenn bei MQTT ein Fehler auftritt, greift „TransportType.Mqtt“ auf MQTT über WebSockets zurück. Wenn Sie nur MQTT über WebSockets angeben möchten, verwenden Sie „TransportType.Mqtt_WebSocket_Only“.
Python Unterstützt standardmäßig MQTT Fügen Sie websockets=True im Befehl hinzu, um den Client zu erstellen.

Das folgende Fragment zeigt, wie bei Verwendung des Azure IoT-SDK für Node.js das Protokoll für MQTT über WebSockets angegeben wird:

var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').MqttWs;
var client = Client.fromConnectionString(deviceConnectionString, Protocol);

Das folgende Fragment zeigt, wie bei Verwendung des Azure IoT-SDK für Python das Protokoll für MQTT über WebSockets angegeben wird:

from azure.iot.device.aio import IoTHubDeviceClient
device_client = IoTHubDeviceClient.create_from_connection_string(deviceConnectionString, websockets=True)

Keep-Alive-Standardtimeout

Um sicherzustellen, dass eine Client/IoT Hub-Verbindung aktiv bleibt, senden sowohl der Dienst als auch der Client einander regelmäßig einen Keep-Alive-Ping. Der Client, der das IoT-SDK verwendet, sendet in dem in der folgenden Tabelle definierten Intervall ein Keep-Alive:

Sprache Keep-Alive-Standardintervall Konfigurierbar
Node.js 180 Sekunden Nein
Java 230 Sekunden Ja
C 240 Sekunden Ja
C# 300 Sekunden* Ja
Python 60 Sekunden Ja

*Das C#-SDK definiert den Standardwert der MQTT-Eigenschaft „KeepAliveInSeconds“ als „300 Sekunden“. Tatsächlich sendet das SDK viermal pro festgelegter Keep-Alive-Dauer eine Pinganforderung. Anders ausgedrückt: Das SDK sendet alle 75 Sekunden einen Keep-Alive-Ping.

Entsprechend der MQTT v3.1.1-Spezifikation ist das Keep-Alive-Pingintervall von IoT Hub das 1,5-fache des Keep-Alive-Clientwerts. IoT Hub begrenzt das maximale serverseitige Timeout jedoch auf 29,45 Minuten (1.767 Sekunden). Diesen Grenzwert gibt es, weil alle Azure-Dienste an das TCP-Leerlauftimeout des Azure-Lastenausgleichs gebunden sind, das 29,45 Minuten beträgt.

So sendet beispielsweise ein Gerät, das das Java SDK verwendet, den Keep-Alive-Ping und verliert dann die Netzwerkkonnektivität. 230 Sekunden später verpasst das Gerät den Keep-Alive-Ping, weil es offline ist. Allerdings schließt IoT Hub die Verbindung nicht sofort, sondern wartet weitere (230 * 1.5) - 230 = 115 Sekunden, bevor es die Geräteverbindung mit der Fehlermeldung 404104 DeviceConnectionClosedRemotely trennt.

Als maximalen Keep-Alive-Wert für Clients können Sie 1767 / 1.5 = 1177 Sekunden festlegen. Das Keep-Alive wird durch jeglichen Datenverkehr zurückgesetzt. Beispielsweise wird Keep-Alive durch eine erfolgreiche Shared Access Signature (SAS)-Tokenaktualisierung zurückgesetzt.

Migrieren einer Geräte-App von AMQP zu MQTT

Wie bereits erwähnt, muss bei Verwendung der Geräte-SDKs und einem Wechsel von AMQP zu MQTT der Protokollparameter in der Clientinitialisierung geändert werden.

Dabei sollten Sie die folgenden Punkte beachten:

  • Bei AMQP werden Fehler für viele Bedingungen zurückgegeben, bei MQTT wird dagegen die Verbindung beendet. Daher müssen an der Ausnahmebehandlungslogik möglicherweise einige Änderungen vorgenommen werden.

  • MQTT unterstützt beim Empfang von Cloud-zu-Gerät-Nachrichten keine reject (Ablehnen)-Vorgänge. Wenn Ihre Back-End-App eine Antwort von der Geräte-App erhalten muss, können Sie direkte Methoden verwenden.

  • AMQP wird im Python SDK nicht unterstützt.

Direktes Verwenden des Protokolls MQTT (als Gerät)

Wenn ein Gerät die Geräte-SDKs nicht verwenden kann, lässt es sich dennoch mithilfe des MQTT-Protokolls an Port 8883 mit den öffentlichen Geräteendpunkten verbinden.

Das Gerät sollte im CONNECT-Paket die folgenden Werte verwenden:

  • Verwenden Sie für das Feld ClientId die deviceId-Eigenschaft.

  • Verwenden Sie {iotHub-hostname}/{device-id}/?api-version=2021-04-12 für das Feld Benutzername, wobei {iotHub-hostname} der vollständige CName für den IoT Hub ist.

    Beispiel: Wenn der Name für den IoT Hub contoso.azure devices.net und der Name des Geräts MyDevice01 lautet, sollte das vollständige Feld Benutzername Folgendes enthalten:

    contoso.azure-devices.net/MyDevice01/?api-version=2021-04-12

    Es wird empfohlen, die API-Version in das Feld einzubeziehen. Andernfalls kann dies zu unerwartetem Verhalten führen.

  • Verwenden Sie im Feld Kennwort ein SAS-Token. Das Format des SAS-Tokens ist das gleiche wie das für die Protokolle HTTPS und AMQP:

    SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}

    Hinweis

    Bei Verwendung der X.509-Zertifikatauthentifizierung sind keine SAS-Tokenkennwörter erforderlich. Weitere Informationen finden Sie unter Tutorial: Erstellen und Hochladen von Zertifikaten zum Testen. Befolgen Sie außerdem die Codeanweisungen im Abschnitt „TLS/SSL-Konfiguration“.

    Weitere Informationen zum Generieren von SAS-Token finden Sie unter Steuern des Zugriffs auf IoT Hub mithilfe von Shared Access Signatures im Abschnitt Verwenden von SAS-Token als Gerät.

    Sie können auch mithilfe der plattformübergreifenden Azure IoT Hub-Erweiterung für Visual Studio Code oder des CLI-Erweiterungsbefehls az iot hub generate-sas-token schnell ein SAS-Token generieren. Anschließend können Sie das SAS-Token zu Testzwecken kopieren und in Ihren eigenen Code einfügen.

Ein Tutorial zum direkten Verwenden von MQTT finden Sie unter Verwenden von MQTT zum Entwickeln eines IoT-Geräteclients ohne Verwendung eines Geräte-SDK.

Verwenden der Azure IoT Hub-Erweiterung für Visual Studio Code

  1. Erweitern Sie in der Seitenleiste den Knoten Geräte unter dem Abschnitt Azure IoT Hub.

  2. Klicken Sie mit der rechten Maustaste auf Ihr IoT-Gerät, und wählen Sie im Kontextmenü SAS-Token für Gerät generieren aus.

  3. Geben Sie die Ablaufzeit (in Stunden) für das SAS-Token in das Eingabefeld ein und drücken Sie dann die EINGABETASTE.

  4. Das SAS-Token wird erstellt und in die Zwischenablage kopiert.

    Das generierte SAS-Token weist die folgende Struktur auf:

    HostName={iotHub-hostname};DeviceId=javadevice;SharedAccessSignature=SharedAccessSignature sr={iotHub-hostname}%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802

    Der folgende Teil des Tokens wird im Feld Kennwort verwendet, um über MQTT eine Verbindung herzustellen:

    SharedAccessSignature sr={iotHub-hostname}%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802

Die Geräte-App kann eine Will-Nachricht im CONNECT-Paket angeben. Für die Geräte-App sollte devices/{device-id}/messages/events/ oder devices/{device-id}/messages/events/{property-bag} als Will-Themenname verwendet werden, um festzulegen, dass Will-Nachrichten als Telemetrienachricht weitergeleitet werden sollen. Wenn die Netzwerkverbindung geschlossen ist, aber vorher kein DISCONNECT-Paket vom Gerät empfangen wurde, sendet IoT Hub in diesem Fall die im CONNECT-Paket bereitgestellte Will-Nachricht an den Telemetriekanal. Der Telemetriekanal kann entweder der Standardendpunkt Ereignisse oder ein benutzerdefinierter Endpunkt sein, der per IoT Hub-Routing definiert wird. Die Nachricht verfügt über die iothub-MessageType-Eigenschaft, der der Wert Will zugewiesen ist.

Direktes Verwenden des Protokolls MQTT (als Modul)

Sie können eine Verbindung mit IoT Hub über MQTT mithilfe einer Modulidentität herstellen, ähnlich wie Sie eine Verbindung mit IoT Hub als Gerät herstellen. Weitere Informationen zum Herstellen einer Verbindung mit IoT Hub über MQTT als Gerät finden Sie unter Direktes Verwenden des MQTT-Protokolls (als Gerät). Sie müssen jedoch die folgenden Werte verwenden:

  • Legen Sie für die Client-ID {device-id}/{module-id} fest.

  • Bei einer Authentifizierung mit Benutzername und Kennwort legen Sie für den Benutzernamen <hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2021-04-12 fest, und verwenden Sie das der Modulidentität zugeordnete SAS-Token als Ihr Kennwort.

  • Verwenden Sie devices/{device-id}/modules/{module-id}/messages/events/ als ein Thema für die Veröffentlichung von Telemetriedaten.

  • Verwenden Sie devices/{device-id}/modules/{module-id}/messages/events/ als Will-Thema.

  • Verwenden Sie devices/{device-id}/modules/{module-id}/# als ein Thema zum Empfangen von Nachrichten.

  • Die Zwillingsthemen GET und PATCH sind bei Modulen und Geräten identisch.

  • Das Zwillingsstatusthema ist bei Modulen und Geräten identisch.

Weitere Informationen zur Verwendung von MQTT bei Modulen finden Sie unter Veröffentlichen und Abonnieren mit IoT Edge. Informieren Sie sich auch ausführlicher über den IoT Edge-Hub-MQTT-Endpunkt.

Beispiel mit MQTT ohne Azure IoT SDK

Das IoT MQTT-Beispielrepository enthält C/C++-, Python- und CLI-Beispiele, die zeigen, wie Sie Telemetrienachrichten senden, Cloud-zu-Gerät-Nachrichten empfangen und mit Gerätezwillingen arbeiten, ohne die Azure-Geräte-SDKs zu verwenden.

Für die C/C++-Beispielen wird die Eclipse Mosquitto-Bibliothek verwendet, für das Python-Beispiel wird Eclipse Paho verwendet und für die CLI-Beispiele wird mosquitto_pub verwendet.

Weitere Informationen finden Sie unter Tutorial: Verwenden von MQTT zum Entwickeln eines IoT-Geräteclients.

TLS/SSL-Konfiguration

Damit Sie das MQTT-Protokoll direkt verwenden können, muss Ihr Client die Verbindung über TLS/SSL herstellen. Wenn Sie versuchen, diesen Schritt zu überspringen, treten Verbindungsfehler auf.

Möglicherweise müssen Sie das DigiCert-Stammzertifikat, das Azure verwendet, herunterladen und darauf verweisen, um eine TLS-Verbindung herstellen zu können. Zwischen dem 15. Februar und dem 15. Oktober 2023 migriert Azure IoT Hub sein TLS-Stammzertifikat vom DigiCert Baltimore-Stammzertifikat zu DigiCert Global Root G2. Während des Migrationszeitraums sollten Sie über beide Zertifikate auf Ihren Geräten verfügen, um die Konnektivität sicherzustellen. Weitere Informationen zur Migration finden Sie unter Migrieren von IoT-Ressourcen zu einem neuen TLS-Stammzertifikat. Weitere Informationen zu diesen Zertifikaten finden Sie auf der Digicert-Website.

Das folgende Beispiel veranschaulicht, wie diese Konfiguration mithilfe der Python-Version der Paho MQTT-Bibliothek durch die Eclipse Foundation implementiert wird.

Installieren Sie zunächst die Paho-Bibliothek aus Ihrer Befehlszeilenumgebung:

pip install paho-mqtt

Implementieren Sie anschließend den Client in einem Python-Skript. Ersetzen Sie diese Platzhalter im folgenden Codeausschnitt:

  • <local path to digicert.cer> ist der Pfad zu einer lokalen Datei, die das DigiCert-Stammzertifikat enthält. Sie können diese Datei erstellen, indem Sie die Zertifikatinformationen aus certs.c in das Azure IoT SDK für C kopieren. Fügen Sie die Zeilen -----BEGIN CERTIFICATE----- und -----END CERTIFICATE----- ein, entfernen Sie die "-Markierungen am Anfang und Ende jeder Zeile, und entfernen Sie die Zeichen \r\n am Ende jeder Zeile.

  • <device id from device registry> ist die ID eines Geräts, das Sie Ihrem IoT Hub hinzugefügt haben.

  • <generated SAS token> ist ein SAS-Token für das Gerät, das wie zuvor in diesem Artikel beschrieben erstellt wurde.

  • <iot hub name> ist der Name Ihres IoT Hubs.

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

Zum Authentifizieren mithilfe eines Gerätezertifikats aktualisieren Sie den vorherigen Codeausschnitt mit den im folgenden Codeausschnitt angegebenen Änderungen. Weitere Informationen zum Vorbereiten der zertifikatbasierten Authentifizierung finden Sie unter Authentifizieren von Geräten mithilfe von X.509-Zertifizierungsstellenzertifikaten im Abschnitt Abrufen eines X.509-Zertifizierungsstellenzertifikats.

# 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)

Senden von D2C-Nachrichten

Nachdem ein Gerät eine Verbindung hergestellt hat, kann es mit devices/{device-id}/messages/events/ oder devices/{device-id}/messages/events/{property-bag} als Themenbezeichnung Nachrichten an den IoT Hub senden. Das Element {property-bag} ermöglicht dem Gerät das Senden von Nachrichten mit weiteren Eigenschaften in einem URL-codierten Format. Beispiel:

RFC 2396-encoded(<PropertyName1>)=RFC 2396-encoded(<PropertyValue1>)&RFC 2396-encoded(<PropertyName2>)=RFC 2396-encoded(<PropertyValue2>)…

Hinweis

Dieses {property_bag}-Element verwendet die gleiche Codierung wie Abfragezeichenfolgen im HTTPS-Protokoll.

Hinweis

Wenn Sie D2C-Nachrichten an ein Azure Storage-Konto weiterleiten und die JSON-Codierung nutzen möchten, müssen Sie die Informationen zu Inhaltstyp und Inhaltscodierung angeben, einschließlich $.ct=application%2Fjson&$.ce=utf-8, als Teil des im Hinweis weiter oben erwähnten {property_bag}.

Die Formate dieser Attribute sind protokollspezifisch. IoT Hub übersetzt diese Attribute in deren entsprechende Systemeigenschaften. Weitere Informationen finden Sie unter Abfragesyntax für das IoT Hub-Nachrichtenrouting im Abschnitt Systemeigenschaften.

In der folgenden Liste wird das implementierungsspezifische Verhalten von IoT Hub beschrieben:

  • IoT Hub unterstützt keine QoS 2-Nachrichten. Wenn eine Geräte-App eine Nachricht mit QoS 2veröffentlicht, schließt IoT Hub die Netzwerkverbindung.

  • IoT Hub speichert Beibehaltungsnachrichten („Retain“) nicht dauerhaft. Wenn ein Gerät eine Nachricht mit auf 1 festgelegtem RETAIN-Flag sendet, fügt IoT Hub der Nachricht die Anwendungseigenschaft mqtt-retain hinzu. In diesem Fall speichert IoT Hub die Beibehaltungsnachricht nicht beständig, sondern übergibt sie an die Back-End-App.

  • IoT Hub unterstützt nur eine aktive MQTT-Verbindung pro Gerät. Jede neue MQTT-Verbindung für dieselbe Geräte-ID bewirkt, dass IoT Hub die vorhandene Verbindung löscht und in IoT Hub-Protokollen die Meldung 400027 ConnectionForcefullyClosedOnNewConnection protokolliert wird.

  • Wenn Sie Nachrichten basierend auf dem Nachrichtentext weiterleiten möchten, müssen Sie zuerst die Eigenschaft „contentType“ (ct) am Ende des MQTT-Themas hinzufügen und deren Wert auf application/json;charset=utf-8 festlegen, wie im folgenden Beispiel gezeigt wird. Weitere Informationen zum Weiterleiten von Nachrichten basierend auf den Nachrichteneigenschaften oder dem Nachrichtentext finden Sie in der Dokumentation „Abfragesyntax für das IoT Hub-Nachrichtenrouting“.

    devices/{device-id}/messages/events/$.ct=application%2Fjson%3Bcharset%3Dutf-8

Weitere Informationen finden Sie unter Senden von Gerät-zu-Cloud- und Cloud-zu-Gerät-Nachrichten mit IoT Hub.

Empfangen von C2D-Nachrichten

Zum Empfangen von Nachrichten von einem IoT Hub muss ein Gerät ein Abonnement unter Verwendung von devices/{device-id}/messages/devicebound/# als Themenfilter einrichten. Der Platzhalter mit mehreren Ebenen # im Themenfilter wird nur verwendet, um dem Gerät das Empfangen von weiteren Eigenschaften im Themennamen zu ermöglichen. IoT Hub lässt die Verwendung der Platzhalter # oder ? für die Filterung von Unterthemen nicht zu. Da IoT Hub kein allgemeiner Nachrichtenbrokerdienst für das Veröffentlichen und Abonnieren ist, unterstützt er nur die dokumentierten Themennamen und -filter. Ein Gerät kann jeweils nur fünf Themen abonnieren.

Das Gerät empfängt Nachrichten von IoT Hub erst, nachdem es dessen gerätespezifischen Endpunkt, der durch den Themenfilter devices/{device-id}/messages/devicebound/# dargestellt wird, erfolgreich abonniert hat. Nachdem ein Abonnement eingerichtet wurde, empfängt das Gerät C2D-Nachrichten, die nach dem Zeitpunkt des Abonnements an das Gerät gesendet wurden. Wenn das Gerät eine Verbindung mit auf 0 festgelegtem CleanSession-Flag herstellt, behält das Abonnement verschiedene Sitzungen übergreifend bei. In diesem Fall empfängt das Gerät beim nächsten Verbindungsaufbau mit CleanSession 0 ausstehende Nachrichten, die ihm gesendet wurden, als es vom Netzwerk getrennt war. Wenn das Gerät jedoch das auf 1 festgelegte CleanSession-Flag verwendet, empfängt es erst dann Nachrichten von IoT Hub, wenn es dessen Geräteendpunkt abonniert hat.

IoT Hub sendet Nachrichten mit dem Themennamendevices/{device-id}/messages/devicebound/ oder devices/{device-id}/messages/devicebound/{property-bag}, wenn Nachrichteneigenschaften vorhanden sind. {property-bag} enthält URL-codierte Schlüssel-Wert-Paare von Nachrichteneigenschaften. Nur Anwendungseigenschaften und vom Benutzer festlegbare Systemeigenschaften (z.B. messageId oder correlationId) sind im Eigenschaftenbehälter enthalten. Systemeigenschaftennamen haben das Präfix $ , Anwendungseigenschaften verwenden den ursprünglichen Eigenschaftennamen ohne Präfix. Weitere Details zum Format des Eigenschaftenbehälters finden Sie unter Senden von D2C-Nachrichten.

Bei Cloud-zu-Gerät-Nachrichten werden die Werte im Eigenschaftenbehälter wie in folgender Tabelle gezeigt dargestellt:

Eigenschaftswert Darstellung BESCHREIBUNG
null key Nur der Schlüssel wird im Eigenschaftenbehälter angezeigt
Leere Zeichenfolge key= Der Schlüssel gefolgt von einem Gleichheitszeichen ohne Wert
nicht NULL, nicht leerer Wert key=value Der Schlüssel gefolgt von einem Gleichheitszeichen und dem Wert

Das folgende Beispiel zeigt einen Eigenschaftenbehälter, der drei Anwendungseigenschaften enthält: prop1 mit einem Wert von null; prop2, eine leere Zeichenfolge („“) und prop3 mit einem Wert „eine Zeichenfolge“.

/?prop1&prop2=&prop3=a%20string

Wenn eine Geräte-App ein Thema mit QoS 2 abonniert, gewährt IoT Hub im SUBACK-Paket maximal die QoS-Ebene 1. Danach übermittelt IoT Hub mithilfe von QoS 1 Nachrichten an das Gerät.

Abrufen der Eigenschaften eines Gerätezwillings

Als Erstes abonniert ein Gerät $iothub/twin/res/#, um die Antworten des Vorgangs zu erhalten. Anschließend wird eine leere Nachricht an das Thema $iothub/twin/GET/?$rid={request id} gesendet, wobei der Wert für request id ausgefüllt ist. Als Nächstes sendet der Dienst eine Antwortnachricht mit den Daten des Gerätezwillings im Thema $iothub/twin/res/{status}/?$rid={request-id}, indem die gleiche request id wie für die Anforderung verwendet wird.

Die Anforderungs-ID kann jeder beliebige gültige Wert für eine Nachrichteneigenschaft sein, und der Status wird als ganze Zahl validiert. Weitere Informationen finden Sie unter Senden von Gerät-zu-Cloud- und Cloud-zu-Gerät-Nachrichten mit IoT Hub.

Der Text der Antwort enthält den Abschnitt mit den Eigenschaften des Gerätezwillings, wie im folgenden Antwortbeispiel gezeigt:

{
    "desired": {
        "telemetrySendFrequency": "5m",
        "$version": 12
    },
    "reported": {
        "telemetrySendFrequency": "5m",
        "batteryLevel": 55,
        "$version": 123
    }
}

Die möglichen Statuscodes lauten:

Status BESCHREIBUNG
200 Erfolg
429 Zu viele Anforderungen (gedrosselt). Weitere Informationen finden Sie unter IoT Hub-Drosselung.
5** Serverfehler

Weitere Informationen finden Sie unter Verstehen und Verwenden von Gerätezwillingen in IoT Hub.

Aktualisieren der gemeldeten Eigenschaften des Gerätezwillings

Zum Aktualisieren der gemeldeten Eigenschaften gibt das Gerät eine Anforderung an den IoT Hub in Form einer Veröffentlichung über ein designiertes MQTT-Thema aus. Nachdem der IoT Hub die Anforderung verarbeitet hat, meldet er den Erfolg oder Misserfolg des Aktualisierungsvorgangs über eine Veröffentlichung in einem anderen Thema zurück. Dieses Thema kann vom Gerät abonniert werden, um es über das Ergebnis der Aktualisierungsanforderung seines Gerätezwillings zu benachrichtigen. Zum Implementieren dieser Art von Anforderungs-/Antwortinteraktion in MQTT verwenden wir das Konzept der Anforderungs-ID ($rid), die anfänglich vom Gerät in seiner Aktualisierungsanforderung bereitgestellt wurde. Diese Anforderungs-ID ist auch in der Antwort von IoT Hub enthalten, damit das Gerät die Antwort mit seiner jeweiligen früheren Anforderung korrelieren kann.

Die folgende Sequenz beschreibt, wie ein Gerät die gemeldeten Eigenschaften in dem Gerätezwilling in IoT Hub aktualisiert:

  1. Ein Gerät muss zuerst das Thema $iothub/twin/res/# abonnieren, um die Antworten des Vorgangs von IoT Hub zu empfangen.

  2. Ein Gerät sendet eine Nachricht, die das Gerätezwillingsupdate enthält, an das Thema $iothub/twin/PATCH/properties/reported/?$rid={request-id}. Diese Nachricht enthält einen request ID-Wert.

  3. Anschließend sendet der Dienst eine Antwortnachricht, die den neuen ETag-Wert für die Sammlung der gemeldeten Eigenschaften enthält, im Thema $iothub/twin/res/{status}/?$rid={request-id}. Diese Antwortnachricht verwendet den gleichen request id-Wert wie die Anforderung.

Der Text der Anforderungsnachricht enthält ein JSON-Dokument mit neuen Werten für gemeldete Eigenschaften. Jeder Member im JSON-Dokument wird aktualisiert, oder der entsprechende Member wird im Dokument des Gerätezwillings hinzugefügt. Wenn ein Member auf null festgelegt wurde, wird er aus dem enthaltenden Objekt gelöscht. Beispiel:

{
    "telemetrySendFrequency": "35m",
    "batteryLevel": 60
}

Die möglichen Statuscodes lauten:

Status BESCHREIBUNG
204 Erfolg (kein Inhalt)
400 Ungültige Anforderung; falsch formatierter JSON-Code
429 Zu viele Anforderungen (gedrosselt), siehe IoT Hub-Drosselung
5** Serverfehler

Der folgende Python-Codeausschnitt veranschaulicht den Aktualisierungsvorgang über MQTT der vom Gerätezwilling mithilfe des Paho MQTT-Clients gemeldeten Eigenschaften:

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)

Nach erfolgreicher Aktualisierung der im vorherigen Codeausschnitt gemeldeten Zwillingseigenschaften hat die Veröffentlichungsnachricht von IoT Hub das folgende Thema: $iothub/twin/res/204/?$rid=1&$version=6, wobei 204 der Statuscode ist, der den Erfolg angibt, sowie $rid=1 der vom Gerät im Code übergebenen Anforderungs-ID und $version der Version des Abschnitts der gemeldeten Eigenschaften der Gerätezwillinge nach der Aktualisierung entspricht.

Weitere Informationen finden Sie unter Verstehen und Verwenden von Gerätezwillingen in IoT Hub.

Empfangen von Aktualisierungsbenachrichtigungen für gewünschte Eigenschaften

Wenn die Verbindung für ein Gerät hergestellt wird, sendet IoT Hub Benachrichtigungen an das Thema $iothub/twin/PATCH/properties/desired/?$version={new-version}. Die Benachrichtigungen enthalten den Inhalt der Aktualisierung, die vom Lösungs-Back-End durchgeführt wird. Beispiel:

{
    "telemetrySendFrequency": "5m",
    "route": null,
    "$version": 8
}

Für Aktualisierungen von Eigenschaften bedeutet die Angabe von null für die Werte, dass der JSON-Objektmember gelöscht wird. Außerdem gibt $version die neue Version des Abschnitts mit den gewünschten Eigenschaften des Zwillings an.

Wichtig

IoT Hub generiert Änderungsbenachrichtigungen nur, wenn Geräte verbunden sind. Achten Sie darauf, den Flow zur Wiederherstellung der Geräteverbindung zu implementieren, um für die gewünschten Eigenschaften die Synchronisierung zwischen dem IoT-Hub und der Geräte-App aufrechtzuerhalten.

Weitere Informationen finden Sie unter Verstehen und Verwenden von Gerätezwillingen in IoT Hub.

Antworten auf eine direkte Methode

Als Erstes muss ein Gerät $iothub/methods/POST/# abonnieren. IoT Hub sendet Methodenanforderungen an das Thema $iothub/methods/POST/{method-name}/?$rid={request-id}, die entweder gültigen JSON-Code oder leeren Text enthalten.

Als Antwort sendet das Gerät eine Nachricht mit einem gültigen JSON-Code oder leerem Text an das Thema $iothub/methods/res/{status}/?$rid={request-id}. In dieser Nachricht muss die Anforderungs-ID derjenigen in der Anforderungsnachricht entsprechen, und Status muss eine ganze Zahl sein.

Weitere Informationen finden Sie unter Verstehen und Aufrufen direkter Methoden von IoT Hub.

Nächste Schritte

Weitere Informationen zur Verwendung von MQTT finden Sie unter:

Weitere Informationen zur Verwendung von IoT-Geräte-SDKs finden Sie unter:

Weitere Informationen zum Planen Ihrer IoT Hub-Bereitstellung finden Sie unter: