Udostępnij za pośrednictwem


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

W tym artykule opisano, jak urządzenia mogą komunikować się z usługą Azure IoT Hub przy użyciu protokołu MQTT. Punkty końcowe urządzeń usługi IoT Hub obsługują łączność urządzeń przy użyciu:

Uwaga

Niektóre funkcje wymienione w tym artykule, takie jak komunikacja chmura-urządzenie, bliźniaki urządzeń i zarządzanie urządzeniami, są dostępne tylko w wariancie standardowym 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 i rozmiaru 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. W związku z tym usługa IoT Hub nie obsługuje niezabezpieczonych połączeń MQTT przez port 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 brokera MQTT hostowanego w chmurze, użyj usługi Azure Event Grid . Usługa Event Grid umożliwia dwukierunkową komunikację między klientami MQTT na elastycznych, hierarchicznych tematach przy użyciu modelu wiadomościowego typu publish-subscribe. Umożliwia również kierowanie komunikatów MQTT do innych usług platformy Azure lub niestandardowych punktów końcowych w celu dalszego przetwarzania.

W poniższej tabeli przedstawiono podsumowanie bieżących różnic w obsłudze MQTT między dwiema usługami:

Usługa IoT Hub Siatka Wydarzeń
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 dla protokołu MQTT w wersji 3.1.1. Obsługa protokołu MQTT v3.1.1 i v5.
Statyczne, wstępnie zdefiniowane tematy. Niestandardowe tematy hierarchiczne z obsługą znaków wieloznacznych.
Brak obsługi emisji z chmury na urządzenie ani komunikacji między urządzeniami. Obsługuje wzorce komunikacji urządzenie-do-chmury, emisje jednokierunkowe z chmury do urządzeń oraz komunikację urządzenie-do-urządzenia.
Maksymalny rozmiar wiadomości: 256 KB. Maksymalny rozmiar komunikatu 512 KB.

Nawiązywanie połączenia z usługą 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:

Wiele zapór firmowych i edukacyjnych blokuje port MQTT (port TCP 8883). Jeśli nie możesz otworzyć portu 8883 w zaporze, użyj MQTT przez WebSockets. Protokół MQTT za pośrednictwem protokołu WebSockets komunikuje się za pośrednictwem portu 443, który jest prawie zawsze otwarty. Aby dowiedzieć się, jak określić protokoły MQTT oraz MQTT za pomocą WebSocket w przypadku korzystania z zestawów SDK Azure IoT, zobacz Korzystanie z zestawów SDK dla urządzeń.

Korzystanie z zestawów SDK urządzeń

Zestawy SDK urządzeń usługi Azure IoT , które obsługują protokół MQTT, są dostępne dla języka 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. Aby używać protokołu MQTT, parametr protokołu klienta musi być ustawiony na MQTT. Można również określić protokół MQTT przez 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 na potrzeby szybszej wymiany komunikatów, należy pamiętać, że dostarczanie nie jest gwarantowane i nie jest potwierdzane. Z tego powodu QoS 0 jest często określany jako "strzel i zapomnij".

Gdy urządzenie łączy się 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
Jawa IotHubClientProtocol. MQTT IotHubClientProtocol.MQTT_WS
C MQTT_Protocol MQTT_WebSocket_Protocol
C# Typ transportu.Mqtt TransportType.Mqtt przełącza się na MQTT za pośrednictwem WebSocketów, jeśli MQTT zawiedzie. Aby określić tylko MQTT przez WebSocket, użyj TransportType.Mqtt_WebSocket_Only
Pyton Domyślnie używa protokołu MQTT Aby utworzyć klienta, dodaj websockets=True w wywołaniu

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)

Ważne

Ten artykuł zawiera kroki łączenia urządzenia przy użyciu sygnatury dostępu współdzielonego, nazywanej również uwierzytelnianiem klucza symetrycznego. Ta metoda uwierzytelniania jest wygodna do testowania i oceny, ale uwierzytelnianie urządzenia przy użyciu certyfikatów X.509 jest bardziej bezpieczne. Aby dowiedzieć się więcej, zobacz Security best practices for IoT solutions Connection security (Najlepsze rozwiązania w zakresie zabezpieczeń rozwiązań > IoT Connection Security).

Domyślny czas podtrzymania aktywności

Aby zapewnić, że połączenie klienta z centrum IoT pozostaje aktywne, zarówno usługa, jak i klient regularnie wysyłają do siebie ping podtrzymujący połączenie. Jeśli używasz jednego z zestawów SDK urządzeń, klient wysyła komunikat o zachowaniu aktywności w interwale zdefiniowanym w poniższej tabeli:

Język Domyślny interwał podtrzymania połączenia Konfigurowalny
Node.js 180 sekund Nie.
Jawa 230 sekundy Nie.
C 240 sekund Tak
C# 300 sek.* Tak
Pyton 60 sekund Tak

*Zestaw SDK języka C# definiuje wartość domyślną właściwości KeepAliveInSeconds MQTT jako 300 sekund. W rzeczywistości SDK wysyła żądanie ping cztery razy w trakcie okresu utrzymania połączenia. Innymi słowy, SDK wysyła sygnał podtrzymujący aktywność co 75 sekund.

W oparciu o specyfikację MQTT w wersji 3.1.1 interwał utrzymywania aktywności ping w usłudze IoT Hub wynosi 1,5 raza wartość utrzymania aktywności klienta; jednak usługa IoT Hub ogranicza maksymalny limit czasu wygaśnięcia po stronie serwera do 29,45 minut (1767 sekund).

Na przykład urządzenie używające Java SDK wysyła ping podtrzymujący połączenie, a następnie traci łączność sieciową. 230 sekund później urządzenie nie odbiera sygnału ping utrzymania aktywności, ponieważ jest 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 DeviceConnectionClosedRemotely.

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

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

Jeśli używasz zestawów SDK urządzeń, aby przełączyć się z używania protokołu AMQP na MQTT, musisz zmienić parametr protokołu w inicjowaniu klienta.

Po zmianie z amQP na MQTT sprawdź 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 może być konieczna zmiana logiki obsługi wyjątków.

  • Protokół MQTT nie obsługuje operacji odrzucania , gdy odbiera komunikaty 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.

Używanie protokołu MQTT bezpośrednio z urządzenia

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

Ważne

Ten artykuł zawiera kroki łączenia urządzenia przy użyciu sygnatury dostępu współdzielonego, nazywanej również uwierzytelnianiem klucza symetrycznego. Ta metoda uwierzytelniania jest wygodna do testowania i oceny, ale uwierzytelnianie urządzenia przy użyciu certyfikatów X.509 jest bardziej bezpieczne. Aby dowiedzieć się więcej, zobacz Security best practices for IoT solutions Connection security (Najlepsze rozwiązania w zakresie zabezpieczeń rozwiązań > IoT Connection Security).

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 nazwa CName centrum IoT.

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

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

    Aby uniknąć nieoczekiwanego zachowania, uwzględnij wersję interfejsu API w polu.

  • W polu Hasło użyj tokenu SAS. Poniższy fragment kodu przedstawia format tokenu SAS:

    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.

    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ć rozszerzenia Azure IoT Hub dla programu Visual Studio Code lub polecenia rozszerzenia CLI az iot hub generate-sas-token w celu wygenerowania tokenu SAS. Następnie możesz skopiować i wkleić token SAS do własnego kodu na potrzeby testowania.

    Rozszerzenie generuje token SAS o następującej strukturze:

    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/ lub devices/{device-id}/messages/events/{property-bag} jako nazwy tematu Will, aby zdefiniować komunikaty Will, które będą 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 trasowanie w usłudze IoT Hub. Komunikat ma właściwość iothub-MessageType z przypisaną wartością Will .

Używanie protokołu MQTT bezpośrednio z modułu

Możesz również nawiązać połączenie z usługą IoT Hub za pośrednictwem protokołu MQTT przy użyciu tożsamości modułu. Takie podejście jest podobne do nawiązywania połączenia jako urządzenia, ale należy 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 na <hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2021-04-12. Jeśli używasz SAS, użyj tokenu SAS skojarzonego z tożsamością modułu jako hasła.

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

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

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

  • Bliźniacze tematy GET i PATCH są takie same w przypadku modułów i urządzeń.

  • Temat statusu bliźniaczego jest taki sam w przypadku modułów i urządzeń.

Aby uzyskać więcej informacji na temat używania protokołu MQTT z modułami, zobacz Punkt końcowy MQTT centrum usługi IoT Edge.

Przykłady z protokołem MQTT bez zestawu SDK urządzenia Azure IoT

Przykładowe repozytorium IoT MQTT zawiera przykłady C/C++, Python oraz CLI, które pokazują, jak wysyłać komunikaty telemetryczne, odbierać komunikaty z chmury do urządzenia i używać bliźniaków urządzeń bez korzystania z zestawów SDK Azure.

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

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

Konfiguracja protokołu TLS

Aby bezpośrednio korzystać z protokołu MQTT, klient musi nawiązać połączenie za pośrednictwem protokołu TLS 1.2. Wszelkie próby pominięcia tego kroku nie powiodą się z powodu błędów połączenia.

Aby nawiązać połączenie TLS, może być konieczne pobranie i skorzystanie z globalnego certyfikatu głównego G2 firmy DigiCert używanego przez Azure. Aby uzyskać więcej informacji na temat tego certyfikatu, 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.

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 twojego 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 przygotowania się do uwierzytelniania opartego na certyfikatach, zobacz sekcję Pobieranie certyfikatu X.509 urzędu certyfikacji w temacie Uwierzytelnianie tożsamości przy użyciu certyfikatów X.509.

# 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 IoT Hub, używając devices/{device-id}/messages/events/ 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>)…

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

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

Uwaga

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 podsumowanie zachowań specyficznych dla implementacji usługi IoT Hub MQTT:

  • 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 utrwala Retain 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 zachowanego komunikatu 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 zapisuje 400027 ConnectionForcefullyClosedOnNewConnection do dzienników usługi IoT Hub

  • Aby kierować komunikaty na podstawie treści komunikatu, najpierw dodaj właściwość ct na końcu tematu MQTT i ustaw jej wartość na , 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 i odbieranie komunikatów 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. Wielopoziomowy symbol wieloznaczny # w filtrze tematu umożliwia urządzeniu odbieranie więcej właściwości w nazwie tematu. Usługa IoT Hub nie zezwala na użycie symboli wieloznacznych # ani ? do filtrowania subtematów. Usługa IoT Hub nie jest brokerem komunikatów publikowania-subskrybowania 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/lub devices/{device-id}/messages/devicebound/{property-bag} gdy istnieją właściwości komunikatu. {property-bag} zawiera właściwości komunikatu w postaci par klucz/wartość zakodowanych jako URL. 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 pakietu właściwości, zobacz Wysyłanie wiadomości z urządzenia do chmury.

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

Wartość 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ść niezerowa, niepusta 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 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źniaka urządzenia

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

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 i odbieranie komunikatów za pomocą usługi IoT Hub.

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

{
    "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ń (ograniczone). Aby uzyskać więcej informacji, zobacz IoT Hub quotas and throttling (Limity przydziału i ograniczanie przepustowości usługi IoT Hub)
5** Błędy serwera

Aby uzyskać więcej informacji, zobacz Zrozumienie i używanie bliźniaczych urządzeń w IoT Hub.

Aktualizowanie zgłoszonych właściwości cyfrowego bliźniaka urządzenia

Aby zaktualizować zgłoszone właściwości, urządzenie wysyła żądanie do usługi IoT Hub, publikując w wyznaczonym temacie MQTT. Gdy usługa IoT Hub przetworzy żądanie, odpowiada, publikując status powodzenia lub niepowodzenia operacji aktualizacji w innym temacie. Urządzenie może subskrybować ten temat, aby otrzymywać powiadomienia o wyniku żądania aktualizacji bliźniaczej. Aby zaimplementować ten typ interakcji żądania/odpowiedzi w MQTT, urządzenie udostępnia identyfikator żądania ($rid) w początkowym żądaniu aktualizacji. Ten identyfikator żądania jest następnie uwzględniony w odpowiedzi z usługi IoT Hub, aby umożliwić urządzeniu skorelowanie odpowiedzi z poprawnym żądaniem.

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

  1. Urządzenie najpierw subskrybuje temat $iothub/twin/res/#, aby mogło odbierać odpowiedzi z usługi IoT Hub.

  2. Urządzenie wysyła komunikat zawierający aktualizację bliźniaka 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 w dokumencie JSON aktualizuje lub dodaje odpowiedni element w bliźniaczym obrazie urządzenia. Członek ustawiony na null usuwa członka 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ń (ograniczone) zgodnie z limitami i ograniczaniem przepustowości usługi IoT Hub
5** Błędy serwera

Poniższy fragment kodu w języku Python demonstruje proces aktualizacji zgłoszonych właściwości bliźniaczych za pośrednictwem protokołu MQTT, używając 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)

Gdy proces aktualizacji zgłoszonych właściwości bliźniaków urządzeń zakończy się pomyślnie, usługa IoT Hub publikuje komunikat w następującym temacie: $iothub/twin/res/204/?$rid=1&$version=6, gdzie 204 jest kodem stanu sygnalizującym powodzenie, $rid=1 odpowiada identyfikatorowi żądania dostarczonemu przez urządzenie w kodzie i $version odpowiada wersji sekcji zgłoszonych właściwości bliźniaków urządzeń po aktualizacji.

Aby uzyskać więcej informacji, zobacz Zrozumienie i używanie bliźniaczych urządzeń w IoT Hub.

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, null wartości oznaczają, że element obiektu JSON jest usuwany. $version Ponadto wskazuje nową wersję sekcji właściwości cyfrowego bliźniaka.

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 Zrozumienie i używanie bliźniaczych urządzeń w IoT Hub.

Odpowiedz na bezpośrednią metodę

Najpierw urządzenie subskrybuje $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: