Komunikacja z centrum IoT przy użyciu protokołu MQTT

W tym artykule opisano, jak urządzenia mogą używać obsługiwanych zachowań MQTT do komunikowania się z usługą Azure IoT Hub. Usługa IoT Hub umożliwia urządzeniom komunikowanie się z punktami końcowymi urządzeń usługi IoT Hub przy użyciu następujących funkcji:

Uwaga

Niektóre funkcje wymienione w tym artykule, takie jak obsługa komunikatów w chmurze, bliźniacze reprezentacje urządzeń i zarządzanie urządzeniami, są dostępne tylko w warstwie Standardowa usługi IoT Hub. Aby uzyskać więcej informacji na temat warstw podstawowej i standardowej/bezpłatnej usługi IoT Hub, zobacz Wybieranie odpowiedniej warstwy usługi IoT Hub dla rozwiązania.

Cała komunikacja urządzenia z usługą IoT Hub musi być zabezpieczona przy użyciu protokołu TLS/SSL. W związku z tym usługa IoT Hub nie obsługuje niezabezpieczonych połączeń za pośrednictwem portu TCP 1883.

Porównanie obsługi protokołu MQTT w usłudze IoT Hub i usłudze Event Grid

Usługa IoT Hub nie jest w pełni funkcjonalnym brokerem MQTT i nie obsługuje wszystkich zachowań określonych w standardzie MQTT w wersji 3.1.1. Jeśli twoje rozwiązanie wymaga MQTT, zalecamy obsługę MQTT w usłudze Azure Event Grid. Usługa Event Grid umożliwia dwukierunkową komunikację między klientami MQTT w elastycznych tematach hierarchicznych przy użyciu modelu obsługi komunikatów pub-sub. Umożliwia również kierowanie komunikatów MQTT do usług platformy Azure lub niestandardowych punktów końcowych w celu dalszego przetwarzania.

W poniższej tabeli opisano różnice w obsłudze MQTT między dwiema usługami:

Usługa IoT Hub Event Grid
Model klient-serwer z ścisłym sprzężeniem między urządzeniami i aplikacjami w chmurze. Model publikowania-subskrybowania, który rozdziela wydawców i subskrybentów.
Ograniczona obsługa funkcji MQTT w wersji 3.1.1 i ograniczona obsługa funkcji MQTT v5 w wersji zapoznawczej. Nie zaplanowano obsługi większej liczby funkcji. Obsługa protokołów MQTT w wersji 3.1.1 i v5 z większą obsługą funkcji i zaplanowaną zgodnością z branży.
Statyczne, wstępnie zdefiniowane tematy. Niestandardowe tematy hierarchiczne z obsługą symboli wieloznacznych.
Brak obsługi emisji z chmury do urządzenia i komunikacji między urządzeniami. Obsługuje emisje z chmury z chmury do chmury i z dużą chmurą do urządzeń oraz wzorce komunikacji między urządzeniami.
Maksymalny rozmiar komunikatu o rozmiarze 256 KB. Maksymalny rozmiar komunikatu 512 KB.

Połączenie do usługi IoT Hub

Urządzenie może używać protokołu MQTT do nawiązywania połączenia z centrum IoT Hub przy użyciu jednej z następujących opcji:

  • Zestawy SDK usługi Azure IoT.
  • Protokół MQTT bezpośrednio.

Port MQTT (port TCP 8883) jest zablokowany w wielu środowiskach sieci firmowych i edukacyjnych. Jeśli nie możesz otworzyć portu 8883 w zaporze, zalecamy użycie protokołu MQTT za pośrednictwem obiektów WebSocket. Protokół MQTT za pośrednictwem protokołu WebSockets komunikuje się za pośrednictwem portu 443, który jest prawie zawsze otwarty w środowiskach sieciowych. Aby dowiedzieć się, jak określić protokoły MQTT i MQTT za pośrednictwem protokołów WebSocket podczas korzystania z zestawów SDK usługi Azure IoT, zobacz Korzystanie z zestawów SDK urządzeń.

Korzystanie z zestawów SDK urządzeń

Zestawy SDK urządzeń, które obsługują protokół MQTT, są dostępne dla języków Java, Node.js, C, C# i Python. Zestawy SDK urządzeń używają wybranego mechanizmu uwierzytelniania w celu nawiązania połączenia z centrum IoT Hub. Aby używać protokołu MQTT, parametr protokołu klienta musi być ustawiony na MQTT. Można również określić protokół MQTT za pośrednictwem obiektów WebSocket w parametrze protokołu klienta. Domyślnie zestawy SDK urządzeń łączą się z usługą IoT Hub z flagą CleanSession ustawioną na 0 i używają usługi QoS 1 do wymiany komunikatów z centrum IoT. Chociaż można skonfigurować funkcję QoS 0 w celu szybszej wymiany komunikatów, należy pamiętać, że dostarczanie nie jest gwarantowane ani potwierdzone. Z tego powodu QoS 0 jest często określany jako "ogień i zapominanie".

Gdy urządzenie jest połączone z centrum IoT Hub, zestawy SDK urządzeń udostępniają metody umożliwiające urządzeniu wymianę komunikatów z centrum IoT Hub.

Poniższa tabela zawiera linki do przykładów kodu dla każdego obsługiwanego języka i określa parametr używany do nawiązywania połączenia z usługą IoT Hub przy użyciu protokołu MQTT lub MQTT za pośrednictwem protokołu WebSockets.

Język Parametr protokołu MQTT MQTT za pośrednictwem parametru protokołu 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# Typ transportu. Mqtt TransportType.Mqtt powraca do MQTT za pośrednictwem obiektów WebSocket, jeśli protokół MQTT ulegnie awarii. Aby określić tylko protokół MQTT za pośrednictwem obiektów WebSocket, użyj TransportType.Mqtt_WebSocket_Only
Python Domyślnie obsługuje protokół MQTT Dodaj websockets=True wywołanie w celu utworzenia klienta

Poniższy fragment przedstawia sposób określania protokołu MQTT za pośrednictwem protokołu WebSockets podczas korzystania z zestawu SDK usługi Azure IoT Node.js:

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

Poniższy fragment przedstawia sposób określania protokołu MQTT za pośrednictwem protokołu WebSockets podczas korzystania z zestawu SDK języka Python usługi Azure IoT:

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

Domyślny limit czasu utrzymywania aktywności

Aby zapewnić, że połączenie klienta/usługi IoT Hub pozostaje aktywne, zarówno usługa, jak i klient regularnie wysyłają do siebie polecenie ping o zachowaniu aktywności . Klient korzystający z zestawu IoT SDK wysyła żywą wartość w interwale zdefiniowanym w poniższej tabeli:

Język Domyślny interwał utrzymania aktywności Konfigurowalny
Node.js 180 sekund Nie.
Java 230 sekund Tak
C 240 sekund Tak
C# 300 sekund* Tak
Python 60 s Tak

*Zestaw SDK języka C# definiuje wartość domyślną właściwości KeepAliveInSeconds MQTT jako 300 sekund. W rzeczywistości zestaw SDK wysyła żądanie ping cztery razy na zestaw czasu trwania utrzymania aktywności. Innymi słowy zestaw SDK wysyła polecenie ping o zachowaniu aktywności co 75 sekund.

Zgodnie ze specyfikacją MQTT w wersji 3.1.1 interwał polecenia ping usługi IoT Hub wynosi 1,5 razy wartość parametru keep-alive klienta, jednak usługa IoT Hub ogranicza maksymalny limit czasu po stronie serwera do 29,45 minut (1767 sekund). Ten limit istnieje, ponieważ wszystkie usługi platformy Azure są powiązane z limitem czasu bezczynności protokołu TCP modułu równoważenia obciążenia platformy Azure, który wynosi 29,45 minut.

Na przykład urządzenie korzystające z zestawu Java SDK wysyła polecenie ping o zachowaniu aktywności, a następnie traci łączność sieciową. 230 sekund później urządzenie przegapi ping keep-alive, ponieważ jest w trybie offline. Jednak usługa IoT Hub nie zamyka połączenia natychmiast — czeka kolejne (230 * 1.5) - 230 = 115 sekundy przed odłączeniem urządzenia z błędem 404104 Device Połączenie ionClosedRemotely.

Maksymalna wartość utrzymania aktywności klienta, którą można ustawić, to 1767 / 1.5 = 1177 sekundy. Każdy ruch resetuje utrzymywania aktywności. Na przykład pomyślne odświeżanie tokenu sygnatury dostępu współdzielonego (SAS) resetuje zachowanie aktywności.

Migrowanie aplikacji urządzenia z protokołu AMQP do MQTT

Jeśli używasz zestawów SDK urządzeń, przełączenie z używania protokołu AMQP na MQTT wymaga zmiany parametru protokołu w inicjowaniu klienta, jak określono wcześniej.

W tym celu należy sprawdzić następujące elementy:

  • Protokół AMQP zwraca błędy dla wielu warunków, podczas gdy protokół MQTT przerywa połączenie. W związku z tym logika obsługi wyjątków może wymagać pewnych zmian.

  • Protokół MQTT nie obsługuje operacji odrzucania podczas odbierania komunikatów z chmury do urządzenia. Jeśli aplikacja zaplecza musi otrzymać odpowiedź z aplikacji urządzenia, rozważ użycie metod bezpośrednich.

  • Protokół AMQP nie jest obsługiwany w zestawie SDK języka Python.

Bezpośrednie używanie protokołu MQTT (jako urządzenie)

Jeśli urządzenie nie może używać zestawów SDK urządzenia, nadal może łączyć się z punktami końcowymi urządzeń publicznych przy użyciu protokołu MQTT na porcie 8883.

W pakiecie CONNECT urządzenie powinno używać następujących wartości:

  • W polu ClientId użyj identyfikatora deviceId.

  • W polu Nazwa użytkownika użyj wartości {iotHub-hostname}/{device-id}/?api-version=2021-04-12, gdzie {iotHub-hostname} jest pełna CName centrum IoT.

    Jeśli na przykład nazwa centrum IoT jest contoso.azure-devices.net , a nazwa urządzenia to MyDevice01, pełne pole Nazwa użytkownika powinno zawierać:

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

    Zaleca się uwzględnienie wersji interfejsu API w polu. W przeciwnym razie może to spowodować nieoczekiwane zachowania.

  • W polu Hasło użyj tokenu SAS. Format tokenu SAS jest taki sam jak w przypadku protokołów HTTPS i AMQP:

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

    Uwaga

    Jeśli używasz uwierzytelniania certyfikatu X.509, hasła tokenu SAS nie są wymagane. Aby uzyskać więcej informacji, zobacz Samouczek: tworzenie i przekazywanie certyfikatów na potrzeby testowania i postępuj zgodnie z instrukcjami dotyczącymi kodu w sekcji Konfiguracja protokołu TLS/SSL.

    Aby uzyskać więcej informacji na temat generowania tokenów SAS, zobacz sekcję Używanie tokenów SAS jako urządzenia w sekcji Kontrola dostępu do usługi IoT Hub przy użyciu sygnatur dostępu współdzielonego.

    Możesz również użyć międzyplatformowego rozszerzenia usługi Azure IoT Hub dla programu Visual Studio Code lub polecenia rozszerzenia interfejsu wiersza polecenia az iot hub generate-sas-token , aby szybko wygenerować token SAS. Następnie możesz skopiować i wkleić token SAS do własnego kodu na potrzeby testowania.

Aby zapoznać się z samouczkiem dotyczącym bezpośredniego używania protokołu MQTT, zobacz Używanie protokołu MQTT do tworzenia klienta urządzenia IoT bez używania zestawu SDK urządzenia.

Korzystanie z rozszerzenia usługi Azure IoT Hub dla programu Visual Studio Code

  1. Na pasku bocznym rozwiń węzeł Urządzenia w sekcji Azure IoT Hub .

  2. Kliknij prawym przyciskiem myszy urządzenie IoT i wybierz pozycję Generuj token SAS dla urządzenia z menu kontekstowego.

  3. Wprowadź czas wygaśnięcia w godzinach dla tokenu SAS w polu wejściowym, a następnie wybierz klawisz Enter.

  4. Token SAS jest tworzony i kopiowany do schowka.

    Wygenerowany token SAS ma następującą strukturę:

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

    Część tego tokenu, która ma być używana jako pole Hasło do nawiązywania połączenia przy użyciu protokołu MQTT, to:

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

Aplikacja urządzenia może określić komunikat Will w pakiecie CONNECT . Aplikacja urządzenia powinna używać devices/{device-id}/messages/events/ nazwy tematu lub devices/{device-id}/messages/events/{property-bag} jako nazwy tematu Will , aby zdefiniować komunikaty, które mają być przekazywane jako komunikat telemetrii. W takim przypadku, jeśli połączenie sieciowe jest zamknięte, ale pakiet DISCONNECT nie został wcześniej odebrany z urządzenia, usługa IoT Hub wysyła komunikat Will dostarczony w pakiecie CONNECT do kanału telemetrii. Kanał telemetrii może być domyślnym punktem końcowym zdarzeń lub niestandardowym punktem końcowym zdefiniowanym przez routing usługi IoT Hub. Komunikat ma właściwość iothub-MessageType z przypisaną wartością Will .

Bezpośrednie używanie protokołu MQTT (jako moduł)

Możesz nawiązać połączenie z usługą IoT Hub za pośrednictwem protokołu MQTT przy użyciu tożsamości modułu, podobnie jak w przypadku nawiązywania połączenia z usługą IoT Hub jako urządzeniem. Aby uzyskać więcej informacji na temat nawiązywania połączenia z usługą IoT Hub za pośrednictwem protokołu MQTT jako urządzenia, zobacz Używanie protokołu MQTT bezpośrednio (jako urządzenie). Należy jednak użyć następujących wartości:

  • Ustaw identyfikator klienta na {device-id}/{module-id}.

  • W przypadku uwierzytelniania przy użyciu nazwy użytkownika i hasła ustaw nazwę użytkownika <hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2021-04-12 na i użyj tokenu SAS skojarzonego z tożsamością modułu jako hasłem.

  • Użyj devices/{device-id}/modules/{module-id}/messages/events/ jako tematu do publikowania danych telemetrycznych.

  • Użyj jako devices/{device-id}/modules/{module-id}/messages/events/ tematu WILL.

  • Użyj devices/{device-id}/modules/{module-id}/# jako tematu do odbierania komunikatów.

  • Bliźniacze tematy GET i PATCH są identyczne dla modułów i urządzeń.

  • Temat stanu bliźniaczej reprezentacji bliźniaczej jest identyczny dla modułów i urządzeń.

Aby uzyskać więcej informacji na temat używania protokołu MQTT z modułami, zobacz Publikowanie i subskrybowanie za pomocą usługi IoT Edge i dowiedz się więcej o punkcie końcowym usługi MQTT centrum usługi IoT Edge.

Przykłady korzystające z protokołu MQTT bez zestawu Azure IoT SDK

Przykładowe repozytorium IoT MQTT zawiera przykłady języków C/C++, Python i interfejsu wiersza polecenia, które pokazują, jak wysyłać komunikaty telemetryczne, odbierać komunikaty z chmury do urządzenia i używać bliźniaczych reprezentacji urządzeń bez korzystania z zestawów SDK urządzeń platformy Azure.

Przykłady języka C/C++ korzystają z biblioteki Eclipse Mosquitto, przykład języka Python używa środowiska Eclipse Paho, a przykłady interfejsu wiersza polecenia używają polecenia mosquitto_pub.

Aby dowiedzieć się więcej, zobacz Samouczek — używanie MQTT do tworzenia klienta urządzenia IoT.

Konfiguracja protokołu TLS/SSL

Aby bezpośrednio korzystać z protokołu MQTT, klient musi nawiązać połączenie za pośrednictwem protokołu TLS/SSL. Próby pominięcia tego kroku kończą się niepowodzeniem z błędami połączenia.

Aby nawiązać połączenie TLS, może być konieczne pobranie i odwołanie do certyfikatu głównego firmy DigiCert używanego przez platformę Azure. Od 15 lutego do 15 października 2023 r. usługa Azure IoT Hub migruje swój certyfikat główny TLS z certyfikatu głównego Firmy DigiCert Baltimore do katalogu głównego G2 firmy DigiCert. W okresie migracji należy mieć oba certyfikaty na urządzeniach, aby zapewnić łączność. Aby uzyskać więcej informacji na temat migracji, zobacz Migrowanie zasobów IoT do nowego głównego certyfikatu TLS Aby uzyskać więcej informacji na temat tych certyfikatów, zobacz witrynę internetową firmy Digicert.

W poniższym przykładzie pokazano, jak zaimplementować tę konfigurację przy użyciu wersji języka Python biblioteki Paho MQTT firmy Eclipse Foundation.

Najpierw zainstaluj bibliotekę Paho ze środowiska wiersza polecenia:

pip install paho-mqtt

Następnie zaimplementuj klienta w skryscie języka Python. Zastąp te symbole zastępcze w poniższym fragmencie kodu:

  • <local path to digicert.cer> to ścieżka do pliku lokalnego, który zawiera certyfikat główny firmy DigiCert. Ten plik można utworzyć, kopiując informacje o certyfikacie z pliku certs.c w zestawie SDK usługi Azure IoT dla języka C. Dołącz wiersze -----BEGIN CERTIFICATE----- i -----END CERTIFICATE-----usuń " znaczniki na początku i na końcu każdego wiersza oraz usuń \r\n znaki na końcu każdego wiersza.

  • <device id from device registry> to identyfikator urządzenia dodanego do centrum IoT.

  • <generated SAS token> to token SAS dla urządzenia utworzonego zgodnie z wcześniejszym opisem w tym artykule.

  • <iot hub name> nazwa centrum 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()

Aby uwierzytelnić się przy użyciu certyfikatu urządzenia, zaktualizuj poprzedni fragment kodu, używając zmian określonych w poniższym fragmencie kodu. Aby uzyskać więcej informacji na temat przygotowywania do uwierzytelniania opartego na certyfikatach, zobacz sekcję Pobieranie certyfikatu X.509 urzędu certyfikacji w temacie Uwierzytelnianie urządzeń przy użyciu certyfikatów X.509 urzędu certyfikacji.

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

Wysyłanie komunikatów z urządzenia do chmury

Po nawiązaniu połączenia urządzenie może wysyłać komunikaty do usługi IoT Hub przy użyciu nazwy devices/{device-id}/messages/events/ tematu lub devices/{device-id}/messages/events/{property-bag} jako nazwy tematu. Element {property-bag} umożliwia urządzeniu wysyłanie komunikatów z innymi właściwościami w formacie zakodowanym w adresie URL. Na przykład:

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

Uwaga

Ten {property_bag} element używa tego samego kodowania co ciągi zapytania w protokole HTTPS.

Uwaga

Jeśli kierujesz komunikaty D2C do konta usługi Azure Storage i chcesz korzystać z kodowania JSON, musisz określić informacje o typie zawartości i kodowaniu zawartości, w tym $.ct=application%2Fjson&$.ce=utf-8, w ramach {property_bag} wymienionej w poprzedniej notatce.

Format tych atrybutów jest specyficzny dla protokołu. Usługa IoT Hub tłumaczy te atrybuty na odpowiednie właściwości systemu. Aby uzyskać więcej informacji, zobacz sekcję Właściwości systemu składni zapytania routingu komunikatów usługi IoT Hub.

Poniższa lista zawiera opis zachowań specyficznych dla implementacji usługi IoT Hub:

  • Usługa IoT Hub nie obsługuje komunikatów QoS 2. Jeśli aplikacja urządzenia publikuje komunikat z usługą QoS 2, usługa IoT Hub zamyka połączenie sieciowe.

  • Usługa IoT Hub nie utrzymuje zachowywania komunikatów. Jeśli urządzenie wysyła komunikat z flagą RETAIN ustawioną na 1, usługa IoT Hub dodaje właściwość aplikacji mqtt-retain do komunikatu. W takim przypadku zamiast utrwalania komunikatu zachowywania usługa IoT Hub przekazuje ją do aplikacji zaplecza.

  • Usługa IoT Hub obsługuje tylko jedno aktywne połączenie MQTT na urządzenie. Każde nowe połączenie MQTT w imieniu tego samego identyfikatora urządzenia powoduje, że usługa IoT Hub usuwa istniejące połączenie i 400027 Połączenie ionForcefullyClosedOnNew Połączenie ion jest zalogowany do dzienników usługi IoT Hub

  • Aby kierować komunikaty na podstawie treści komunikatu, musisz najpierw dodać właściwość "contentType" (ct) na końcu tematu MQTT i ustawić jego wartość na tak application/json;charset=utf-8 , jak pokazano w poniższym przykładzie. Aby uzyskać więcej informacji na temat routingu komunikatów na podstawie właściwości komunikatów lub treści komunikatów, zobacz dokumentację składni zapytania routingu komunikatów usługi IoT Hub.

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

Aby uzyskać więcej informacji, zobacz Wysyłanie komunikatów urządzenie-chmura i chmura-urządzenie za pomocą usługi IoT Hub.

Odbieranie komunikatów z chmury do urządzenia

Aby odbierać komunikaty z usługi IoT Hub, urządzenie powinno subskrybować za pomocą devices/{device-id}/messages/devicebound/# filtru tematu. Wielowymiarowe symbole wieloznaczne # w filtrze tematu są używane tylko w celu umożliwienia urządzeniu odbierania większej liczby właściwości w nazwie tematu. Usługa IoT Hub nie zezwala na używanie # symboli wieloznacznych ani ? do filtrowania podtopień. Ponieważ usługa IoT Hub nie jest brokerem komunikatów pub-sub ogólnego przeznaczenia, obsługuje tylko udokumentowane nazwy tematów i filtry tematów. Urządzenie może subskrybować tylko pięć tematów jednocześnie.

Urządzenie nie odbiera żadnych komunikatów z usługi IoT Hub do momentu pomyślnego zasubskrybowania punktu końcowego specyficznego dla urządzenia reprezentowanego przez filtr tematu devices/{device-id}/messages/devicebound/# . Po ustanowieniu subskrypcji urządzenie odbiera komunikaty z chmury do urządzenia, które zostały wysłane do niej po upływie czasu subskrypcji. Jeśli urządzenie łączy się z flagą CleanSession ustawioną na 0, subskrypcja będzie utrwalana w różnych sesjach. W takim przypadku przy następnym połączeniu urządzenia z funkcją CleanSession 0 odbiera wszystkie zaległe komunikaty wysyłane do niego podczas rozłączenia. Jeśli urządzenie używa flagi CleanSession ustawionej na 1 , nie odbiera żadnych komunikatów z usługi IoT Hub, dopóki nie zasubskrybuje swojego punktu końcowego urządzenia.

Usługa IoT Hub dostarcza komunikaty z nazwądevices/{device-id}/messages/devicebound/ tematu lub devices/{device-id}/messages/devicebound/{property-bag} gdy istnieją właściwości komunikatu. {property-bag} zawiera pary klucz/wartość zakodowane w adresie URL właściwości komunikatu. W torbie właściwości właściwości są uwzględniane tylko właściwości aplikacji i właściwości systemu ustawiane przez użytkownika (takie jak messageId lub correlationId). Nazwy właściwości systemowych mają prefiks $, właściwości aplikacji używają oryginalnej nazwy właściwości bez prefiksu. Aby uzyskać więcej informacji na temat formatu torby właściwości, zobacz Wysyłanie komunikatów z urządzenia do chmury.

W komunikatach chmura-urządzenie wartości w torbie właściwości są reprezentowane jak w poniższej tabeli:

Wartości właściwości Reprezentacja opis
null key Tylko klucz jest wyświetlany w torbie właściwości
pusty ciąg key= Klucz, po którym następuje znak równości bez wartości
wartość non-null, nonempty key=value Klucz, po którym następuje znak równości i wartość

W poniższym przykładzie przedstawiono torbę właściwości zawierającą trzy właściwości aplikacji: prop1 z wartością null; prop2, pusty ciąg (""); i prop3 z wartością "ciąg".

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

Gdy aplikacja urządzenia subskrybuje temat z usługą QoS 2, usługa IoT Hub przyznaje maksymalny poziom QoS 1 w pakiecie SUBACK . Następnie usługa IoT Hub dostarcza komunikaty do urządzenia przy użyciu usługi QoS 1.

Pobieranie właściwości bliźniaczej reprezentacji urządzenia

Najpierw urządzenie subskrybuje $iothub/twin/res/#element , aby otrzymywać odpowiedzi operacji. Następnie wysyła pustą wiadomość do tematu $iothub/twin/GET/?$rid={request id}z wypełniona wartością identyfikatora żądania. Następnie usługa wysyła komunikat odpowiedzi zawierający dane bliźniaczej reprezentacji urządzenia w temacie $iothub/twin/res/{status}/?$rid={request-id}, używając tego samego identyfikatora żądania co żądanie.

Identyfikator żądania może być dowolną prawidłową wartością właściwości komunikatu, a stan jest weryfikowany jako liczba całkowita. Aby uzyskać więcej informacji, zobacz Wysyłanie komunikatów urządzenie-chmura i chmura-urządzenie za pomocą usługi IoT Hub.

Treść odpowiedzi zawiera sekcję właściwości bliźniaczej reprezentacji urządzenia, jak pokazano w poniższym przykładzie odpowiedzi:

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

Możliwe kody stanu to:

Stan opis
200 Sukces
429 Zbyt wiele żądań (ograniczane). Aby uzyskać więcej informacji, zobacz Ograniczanie przepustowości usługi IoT Hub
5** Błędy serwera

Aby uzyskać więcej informacji, zobacz Opis bliźniaczej reprezentacji urządzenia w usłudze IoT Hub oraz sposoby jej używania.

Aktualizowanie zgłoszonych właściwości bliźniaczej reprezentacji urządzenia

Aby zaktualizować zgłoszone właściwości, urządzenie wysyła żądanie do usługi IoT Hub za pośrednictwem publikacji w wyznaczonym temacie MQTT. Gdy usługa IoT Hub przetworzy żądanie, odpowiada na stan powodzenia lub niepowodzenia operacji aktualizacji za pośrednictwem publikacji do innego tematu. Urządzenie może subskrybować ten temat, aby powiadomić go o wyniku żądania aktualizacji bliźniaczej reprezentacji. Aby zaimplementować ten typ interakcji żądania/odpowiedzi w MQTT, używamy pojęcia identyfikatora żądania ($rid) dostarczonego początkowo przez urządzenie w żądaniu aktualizacji. Ten identyfikator żądania jest również uwzględniony w odpowiedzi z usługi IoT Hub, aby umożliwić urządzeniu skorelowanie odpowiedzi z konkretnym wcześniejszym żądaniem.

W poniższej sekwencji opisano, jak urządzenie aktualizuje zgłaszane właściwości w bliźniaczej reprezentacji urządzenia w usłudze IoT Hub:

  1. Urządzenie musi najpierw subskrybować $iothub/twin/res/# temat, aby otrzymywać odpowiedzi operacji z usługi IoT Hub.

  2. Urządzenie wysyła komunikat zawierający aktualizację bliźniaczej reprezentacji urządzenia do tematu $iothub/twin/PATCH/properties/reported/?$rid={request-id} . Ten komunikat zawiera wartość identyfikatora żądania.

  3. Następnie usługa wysyła komunikat odpowiedzi zawierający nową wartość elementu ETag dla kolekcji zgłoszonych właściwości w temacie $iothub/twin/res/{status}/?$rid={request-id}. Ten komunikat odpowiedzi używa tego samego identyfikatora żądania co żądanie.

Treść komunikatu żądania zawiera dokument JSON zawierający nowe wartości dla zgłoszonych właściwości. Każdy element członkowski w dokumencie JSON aktualizuje lub dodaje odpowiedni element członkowski w dokumencie bliźniaczej reprezentacji urządzenia. Element członkowski ustawiony na usunięcie null elementu członkowskiego z obiektu zawierającego. Na przykład:

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

Możliwe kody stanu to:

Stan opis
204 Powodzenie (żadna zawartość nie jest zwracana)
400 Nieprawidłowe żądanie. Źle sformułowany kod JSON
429 Zbyt wiele żądań (ograniczane) zgodnie z ograniczaniem przepustowości usługi IoT Hub
5** Błędy serwera

Poniższy fragment kodu języka Python demonstruje proces aktualizacji właściwości zgłoszonych przez bliźniaczą reprezentację za pośrednictwem protokołu MQTT przy użyciu klienta Paho 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)

Po pomyślnym zakończeniu procesu aktualizacji zgłoszonych właściwości bliźniaczej reprezentacji w poprzednim fragmencie kodu komunikat publikacji z usługi IoT Hub ma następujący temat: $iothub/twin/res/204/?$rid=1&$version=6, gdzie 204 jest kodem stanu wskazującym powodzenie, $rid=1 odpowiada identyfikatorowi żądania dostarczonemu przez urządzenie w kodzie i $version odpowiada wersji raportowanych właściwości bliźniaczych reprezentacji urządzenia po aktualizacji.

Aby uzyskać więcej informacji, zobacz Opis bliźniaczej reprezentacji urządzenia w usłudze IoT Hub oraz sposoby jej używania.

Otrzymywanie powiadomień o aktualizacji żądanych właściwości

Gdy urządzenie jest połączone, usługa IoT Hub wysyła powiadomienia do tematu $iothub/twin/PATCH/properties/desired/?$version={new-version}, który zawiera zawartość aktualizacji wykonywanej przez zaplecze rozwiązania. Na przykład:

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

Jeśli chodzi o aktualizacje właściwości, wartości oznaczają, null że element członkowski obiektu JSON jest usuwany. $version Ponadto wskazuje nową wersję żądanej sekcji właściwości bliźniaczej reprezentacji.

Ważne

Usługa IoT Hub generuje powiadomienia o zmianie tylko wtedy, gdy urządzenia są połączone. Pamiętaj, aby zaimplementować przepływ ponownego łączenia urządzenia, aby zachować synchronizację żądanych właściwości między usługą IoT Hub i aplikacją urządzenia.

Aby uzyskać więcej informacji, zobacz Opis bliźniaczej reprezentacji urządzenia w usłudze IoT Hub oraz sposoby jej używania.

Odpowiadanie na metodę bezpośrednią

Najpierw urządzenie musi subskrybować usługę $iothub/methods/POST/#. Usługa IoT Hub wysyła żądania metody do tematu $iothub/methods/POST/{method-name}/?$rid={request-id}, z prawidłowym kodem JSON lub pustą treścią.

Aby odpowiedzieć, urządzenie wysyła komunikat z prawidłowym kodem JSON lub pustą treścią do tematu $iothub/methods/res/{status}/?$rid={request-id}. W tym komunikacie identyfikator żądania musi być zgodny z identyfikatorem w komunikacie żądania, a stan musi być liczbą całkowitą.

Aby uzyskać więcej informacji, zobacz Omówienie i wywoływanie metod bezpośrednich z usługi IoT Hub.

Następne kroki

Aby dowiedzieć się więcej na temat korzystania z MQTT, zobacz:

Aby dowiedzieć się więcej na temat korzystania z zestawów SDK urządzeń IoT, zobacz:

Aby dowiedzieć się więcej na temat planowania wdrożenia usługi IoT Hub, zobacz: