Comunicare con un hub IoT usando il protocollo MQTT

Questo articolo descrive come i dispositivi possono usare i comportamenti MQTT supportati per comunicare con hub IoT di Azure. L'hub IoT consente ai dispositivi di comunicare con gli endpoint dei dispositivi dell'hub IoT usando:

  • MQTT v3.1.1 sulla porta TCP 8883
  • MQTT v3.1.1 su WebSocket sulla porta TCP 443.

Nota

Alcune delle funzionalità indicate in questo articolo, come la messaggistica da cloud a dispositivo, i dispositivi gemelli e la gestione dei dispositivi, sono disponibili solo nel livello Standard dell'hub IoT. Per altre informazioni sui livelli Basic e Standard/Gratuito dell'hub IoT, vedere Scegliere il livello appropriato dell'hub IoT per la soluzione.

Tutte le comunicazioni del dispositivo con l'hub IoT devono essere protette tramite TLS/SSL. Pertanto, hub IoT non supporta connessioni non sicure sulla porta TCP 1883.

Confrontare il supporto di MQTT in hub IoT e Griglia di eventi

hub IoT non è un broker MQTT completo e non supporta tutti i comportamenti specificati nello standard MQTT v3.1.1. Se la soluzione richiede MQTT, è consigliabile supportare MQTT in Griglia di eventi di Azure. Griglia di eventi consente la comunicazione bidirezionale tra i client MQTT in argomenti gerarchici flessibili usando un modello di messaggistica pub-sub. Consente anche di instradare i messaggi MQTT ai servizi di Azure o agli endpoint personalizzati per un'ulteriore elaborazione.

La tabella seguente illustra le differenze nel supporto MQTT tra i due servizi:

Hub IoT Griglia di eventi
Modello client-server con accoppiamento stretto tra dispositivi e app cloud. Modello di pubblicazione-sottoscrizione che separa i server di pubblicazione e i sottoscrittori.
Supporto limitato delle funzionalità per MQTT v3.1.1 e supporto limitato delle funzionalità per MQTT v5 in anteprima. Non è previsto un maggiore supporto per le funzionalità. Supporto del protocollo MQTT v3.1.1 e v5, con maggiore supporto delle funzionalità e conformità del settore pianificati.
Argomenti statici predefiniti. Argomenti gerarchici personalizzati con supporto con caratteri jolly.
Nessun supporto per le trasmissioni da cloud a dispositivo e la comunicazione da dispositivo a dispositivo. Supporta le trasmissioni da dispositivo a cloud, da cloud a dispositivo ad alta ventola e dai modelli di comunicazione da dispositivo a dispositivo.
Dimensioni massime messaggi di 256 KB. Dimensioni massime del messaggio di 512 KB.

Connessione all'hub IoT

Un dispositivo può usare il protocollo MQTT per connettersi a un hub IoT usando una delle opzioni seguenti:

La porta MQTT (porta TCP 8883) è bloccata in molti ambienti di rete aziendali e didattici. Se non è possibile aprire la porta 8883 nel firewall, è consigliabile usare MQTT su WebSocket. MQTT su WebSocket comunica sulla porta 443, quasi sempre aperta negli ambienti di rete. Per informazioni su come specificare i protocolli MQTT e MQTT su WebSocket quando si usano gli SDK di Azure IoT, vedere Uso degli SDK per dispositivi.

Uso degli SDK per dispositivi

Gli SDK per dispositivi che supportano il protocollo MQTT sono disponibili per Java, Node.js, C, C# e Python. Gli SDK del dispositivo usano il meccanismo di autenticazione scelto per stabilire una connessione a un hub IoT. Per usare il protocollo MQTT, il parametro del protocollo del client deve essere impostato su MQTT. È anche possibile specificare MQTT su WebSocket nel parametro del protocollo client. Per impostazione predefinita, gli SDK per dispositivi si connettono a un hub IoT con il flag CleanSession impostato su 0 e usano QoS 1 per lo scambio di messaggi con l'hub IoT. Sebbene sia possibile configurare QoS 0 per uno scambio di messaggi più veloce, è consigliabile notare che il recapito non è garantito né riconosciuto. Per questo motivo, QoS 0 viene spesso definito "fuoco e dimentica".

Quando un dispositivo è connesso a un hub IoT, gli SDK per dispositivi forniscono i metodi che consentono al dispositivo di scambiare messaggi con un hub IoT.

La tabella seguente contiene collegamenti a esempi di codice per ogni lingua supportata e specifica il parametro da usare per stabilire una connessione a hub IoT usando MQTT o MQTT su protocollo WebSocket.

Lingua Parametro del protocollo MQTT Parametro del protocollo MQTT su WebSocket
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 TransportType.Mqtt esegue il fallback a MQTT su WebSocket se MQTT ha esito negativo. Per specificare MQTT solo su WebSocket, usare TransportType.Mqtt_WebSocket_Only
Python Supporta il protocollo MQTT per impostazione predefinita Aggiungere websockets=True nella chiamata per creare il client

Il frammento seguente illustra come specificare il protocollo MQTT su WebSocket quando si usa Azure IoT Node.js SDK:

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

Il frammento seguente illustra come specificare il protocollo MQTT su WebSocket quando si usa Azure IoT Python SDK:

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

Importante

Questo articolo include la procedura per connettere un dispositivo usando una firma di accesso condiviso, altrimenti chiamata autenticazione con chiave simmetrica. Questo metodo di autenticazione è comodo per i test e le valutazioni, ma l'autenticazione tramite certificati X.509 rappresenta un approccio più sicuro. Per scoprire di più, vedere Procedure consigliate per la sicurezza > Sicurezza della connessione.

Timeout keep-alive predefinito

Per garantire la continuità di una connessione tra client e hub IoT, sia il servizio che il client si inviano reciprocamente un ping keep-alive con regolarità. Il client che usa l’IoT SDK invia un comando keep-alive all’intervallo definito nella tabella seguente:

Lingua Intervallo di keep-alive predefinito Configurabile
Node.js 180 secondi No
Java 230 secondi
A 240 secondi
C# 300 secondi*
Python 60 secondi

*L'SDK C# definisce il valore predefinito della proprietà MQTT KeepAliveInSeconds come 300 secondi. In realtà, l'SDK invia una richiesta ping quattro volte per ogni set di durata keep-alive. In altre parole, l'SDK invia un ping keep-alive una volta ogni 75 secondi.

In seguito alla specifica MQTT v3.1.1, l'intervallo ping keep-alive di hub IoT è 1,5 volte il valore keep-alive del client. Tuttavia, hub IoT limita il timeout massimo lato server a 29,45 minuti (1.767 secondi). Questo limite esiste perché tutti i servizi di Azure sono associati al timeout di inattività TCP di Azure Load Balancer, ovvero 29,45 minuti.

Ad esempio, un dispositivo che usa Java SDK invia il ping keep-alive, quindi perde la connettività di rete. 230 secondi dopo, il dispositivo perde il ping keep-alive perché è offline. Tuttavia, l'hub IoT non chiude la connessione immediatamente. Attende altri (230 * 1.5) - 230 = 115 secondi prima di disconnettere il dispositivo con l'errore 404104 DeviceConnectionClosedRemotely.

Il valore di keep-alive massimo del client che è possibile impostare è di 1767 / 1.5 = 1177 secondi. Qualsiasi traffico reimposta il keep-alive. Ad esempio, un aggiornamento corretto del token di firma di accesso condiviso reimposta il keep-alive.

Migrazione di un'app per dispositivo da AMQP a MQTT

Se si usano gli SDK per dispositivi, il passaggio dall'uso di AMQP a MQTT richiede la modifica del parametro del protocollo nell'inizializzazione client, come indicato in precedenza.

Quando si esegue questa operazione, controllare gli elementi seguenti:

  • AMQP restituisce errori per diverse condizioni, mentre MQTT termina la connessione. Di conseguenza, la logica di gestione delle eccezioni potrebbe richiedere alcune modifiche.

  • MQTT non supporta le operazioni di rifiuto durante la ricezione di messaggi da cloud a dispositivo. Se l'app back-end deve ricevere una risposta dall'app per dispositivo, considerare la possibilità di usare metodi diretti.

  • AMQP non è supportato in Python SDK.

Uso diretto del protocollo MQTT (come dispositivo)

Se un dispositivo non può usare gli SDK del dispositivo, può comunque connettersi agli endpoint del dispositivo pubblico usando il protocollo MQTT sulla porta 8883.

Nel pacchetto CONNECT il dispositivo deve usare i valori seguenti:

  • Per il campo ClientId usare deviceId.

  • Per il campo Nome utente usare {iotHub-hostname}/{device-id}/?api-version=2021-04-12, dove {iotHub-hostname} è pieno CName dell'hub IoT.

    Ad esempio, se il nome dell'hub IoT è contoso.azure-devices.net e il nome del dispositivo è MyDevice01, il campo Username completo deve contenere:

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

    È consigliabile includere api-version nel campo . In caso contrario, potrebbe causare comportamenti imprevisti.

  • Per il campo Password usare un token di firma di accesso condiviso. Il formato del token di firma di accesso condiviso è identico a quello per i protocolli HTTPS e AMQP:

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

    Nota

    Le password di token SAS non sono obbligatorie se si usa l'autenticazione dei certificati X.509. Per altre informazioni, vedere Esercitazione: Creare e caricare certificati per il test e seguire le istruzioni sul codice nella sezione Configurazione TLS/SSL.

    Per altre informazioni su come generare token di firma di accesso condiviso, vedere la sezione Usare token di firma di accesso condiviso come dispositivo in Controllare l'accesso alle hub IoT usando firme di accesso condiviso.

    È anche possibile usare l'estensione hub IoT di Azure multipiattaforma per Visual Studio Code o il comando di estensione dell'interfaccia della riga di comando az iot hub generate-sas-token per generare rapidamente un token di firma di accesso condiviso. È quindi possibile copiare e incollare il token di firma di accesso condiviso nel proprio codice a scopo di test.

Per un'esercitazione sull'uso diretto di MQTT, vedere Usare MQTT per sviluppare un client per dispositivi IoT senza usare un SDK per dispositivi.

Uso dell'estensione hub IoT di Azure per Visual Studio Code

  1. Nella barra laterale espandere il nodo Dispositivi nella sezione hub IoT di Azure.

  2. Fare clic con il pulsante destro del mouse sul dispositivo IoT e scegliere Genera token di firma di accesso condiviso per dispositivo dal menu di scelta rapida.

  3. Immettere l'ora di scadenza, espressa in ore, per il token di firma di accesso condiviso nella casella di input e quindi selezionare invio chiave.

  4. Il token di firma di accesso condiviso viene creato e copiato negli appunti.

    Il token SAS generato ha questa struttura:

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

    La porzione di questo token da usare come campo Password per connettersi usando MQTT è:

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

L'app per dispositivo può specificare un messaggio Will nel pacchetto CONNECT. L'app per dispositivo deve usare devices/{device-id}/messages/events/ o devices/{device-id}/messages/events/{property-bag} come nome di argomento Will per definire i messaggi Will da inoltrare come messaggi di telemetria. In questo caso, se la connessione di rete è chiusa, ma un pacchetto DISCONNECT non è stato ricevuto in precedenza dal dispositivo, hub IoT invia il messaggio Will fornito nel pacchetto CONNECT al canale di telemetria. Quest'ultimo può essere l'endpoint Events predefinito o un endpoint personalizzato definito dal routing dell'hub IoT. Alla proprietà iothub-MessageType del messaggio è assegnato un valore Will.

Uso diretto del protocollo MQTT (come modulo)

È possibile connettersi a hub IoT tramite MQTT usando un'identità del modulo, analogamente alla connessione a hub IoT come dispositivo. Per altre informazioni sulla connessione a hub IoT su MQTT come dispositivo, vedere Uso diretto del protocollo MQTT (come dispositivo). Tuttavia, è necessario usare i valori seguenti:

  • Impostare l'ID client su {device-id}/{module-id}.

  • Se si esegue l'autenticazione con nome utente e password, impostare il nome utente <hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2021-04-12 e usare il token di firma di accesso condiviso associato all'identità modulo come password.

  • Usare devices/{device-id}/modules/{module-id}/messages/events/ come argomento per la pubblicazione dei dati di telemetria.

  • Usare devices/{device-id}/modules/{module-id}/messages/events/ come argomento WILL.

  • Usare devices/{device-id}/modules/{module-id}/# come argomento per la ricezione di messaggi.

  • Gli argomenti relativi ai comandi PATCH e GET per i dispositivi gemelli sono identici anche per i moduli.

  • L'argomento relativo allo stato dei dispositivi gemelli è identico anche per i moduli.

Per altre informazioni sull'uso di MQTT con i moduli, vedere Pubblicare e sottoscrivere con IoT Edge e altre informazioni sull'endpoint MQTT dell'hub IoT Edge.

Esempi che usano MQTT senza Azure IoT SDK

Il repository di esempio MQTT IoT contiene esempi di C/C++, Python e dell'interfaccia della riga di comando che illustrano come inviare messaggi di telemetria, ricevere messaggi da cloud a dispositivo e usare dispositivi gemelli senza usare gli SDK per dispositivi di Azure.

Gli esempi C/C++ usano la libreria Eclipse Mosquitto , l'esempio Python usa Eclipse Paho e gli esempi dell'interfaccia della riga di comando usano mosquitto_pub.

Per altre informazioni, vedere Esercitazione - Usare MQTT per sviluppare un client di dispositivi IoT.

Configurazione TLS/SSL

Per usare direttamente il protocollo MQTT, il client deve connettersi tramite TLS/SSL, altrimenti si verificheranno errori di connessione.

Per stabilire una connessione TLS, potrebbe essere necessario scaricare e fare riferimento al certificato radice DigiCert usato da Azure. Tra il 15 febbraio e il 15 ottobre 2023, hub IoT di Azure sta eseguendo la migrazione del certificato radice TLS dal certificato radice DigiCert Baltimore al DigiCert Global Root G2. Durante il periodo di migrazione, è necessario disporre di entrambi i certificati nei dispositivi per garantire la connettività. Per altre informazioni sulla migrazione, vedere Eseguire la migrazione delle risorse IoT a una nuova radice del certificato TLS. Per altre informazioni su questi certificati, vedere il sito Web di Digicert.

L'esempio seguente illustra come implementare questa configurazione usando la versione Python della libreria Paho MQTT di Eclipse Foundation.

È prima necessario installare la libreria Paho dall'ambiente della riga di comando:

pip install paho-mqtt

Implementare poi il client in uno script Python. Sostituire questi segnaposto nel frammento di codice seguente:

  • <local path to digicert.cer> è il percorso di un file locale che contiene il certificato radice DigiCert. È possibile creare questo file copiando le informazioni sul certificato da certs.c negli Azure IoT SDK per C. Includere le righe -----BEGIN CERTIFICATE----- e -----END CERTIFICATE-----, rimuovere i contrassegni " all'inizio e alla fine di ogni riga e rimuovere i caratteri \r\n alla fine di ogni riga.

  • <device id from device registry> è l'ID di un dispositivo che è stato aggiunto all'hub IoT.

  • <generated SAS token> è un token SAS per il dispositivo creato come descritto in precedenza in questo articolo.

  • <iot hub name> nome dell'hub IoT.

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

Per eseguire l'autenticazione usando un certificato del dispositivo, aggiornare il frammento di codice precedente con le modifiche specificate nel frammento di codice seguente. Per altre informazioni su come preparare l'autenticazione basata su certificati, vedere la sezione Ottenere un certificato DELLA CA X.509 di Autenticare i dispositivi con certificati DELLA CA 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)

Invio di messaggi da dispositivo a cloud

Dopo la connessione di un dispositivo, può inviare messaggi a hub IoT utilizzando devices/{device-id}/messages/events/ o devices/{device-id}/messages/events/{property-bag} come Nome argomento. L'elemento {property-bag} consente al dispositivo di inviare messaggi con altre proprietà in un formato con codifica URL. Ad esempio:

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

Nota

L’elemento {property_bag} usa la stessa codifica delle stringhe di query nel protocollo HTTPS.

Nota

Se si instradano i messaggi D2C a un account Archiviazione di Azure e si vuole sfruttare la codifica JSON, è necessario specificare le informazioni sul tipo di contenuto e sulla codifica del contenuto, incluso $.ct=application%2Fjson&$.ce=utf-8, come parte della {property_bag} nota precedente.

Il formato di questi attributi è specifico del protocollo. hub IoT converte questi attributi nelle proprietà di sistema corrispondenti. Per altre informazioni, vedere la sezione Proprietà di sistema di hub IoT sintassi delle query di routing dei messaggi.

L'elenco seguente descrive hub IoT comportamenti specifici dell'implementazione:

  • hub IoT non supporta i messaggi QoS 2. Quando un'app per dispositivo pubblica un messaggio con QoS 2, l'hub IoT chiude la connessione di rete.

  • hub IoT non mantiene i messaggi di conservazione. Se un dispositivo invia un messaggio con il flag RETAIN impostato su 1, hub IoT aggiunge la proprietà dell'applicazione mqtt-retain al messaggio. In tal caso, anziché rendere persistente il messaggio di mantenimento, l'hub IoT passa invece all'app back-end.

  • L'hub IoT supporta solo una connessione MQTT attiva per ogni dispositivo. Qualsiasi nuova connessione MQTT per conto dello stesso ID dispositivo causa hub IoT di eliminare la connessione esistente e 400027 ConnectionForcefullyClosedOnNewConnection viene connesso hub IoT Log

  • Per instradare i messaggi in base al corpo del messaggio, è necessario innanzitutto aggiungere la proprietà 'contentType' (ct) alla fine dell'argomento MQTT e impostarne il valore come application/json;charset=utf-8 illustrato nell'esempio seguente. Per altre informazioni sul routing dei messaggi in base alle proprietà del messaggio o al corpo del messaggio, vedere la documentazione sulla sintassi delle query di routing dei messaggi hub IoT.

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

Per altre informazioni, vedere Inviare messaggi da dispositivo a cloud e da cloud a dispositivo con hub IoT.

Ricezione di messaggi da cloud a dispositivo

Per ricevere messaggi dall'hub IoT, un dispositivo deve eseguire la sottoscrizione con devices/{device-id}/messages/devicebound/# come filtro di argomento. Il carattere jolly # multilivello nel filtro argomento viene usato solo per consentire al dispositivo di ricevere più proprietà nel nome dell'argomento. hub IoT non consente l'utilizzo dei # caratteri jolly o ? per filtrare gli argomenti secondari. Poiché hub IoT non è un broker di messaggistica pub-sub per utilizzo generico, supporta solo i nomi e i filtri degli argomenti documentati. Un dispositivo può sottoscrivere solo cinque argomenti alla volta.

Il dispositivo non riceve messaggi da hub IoT finché non ha sottoscritto correttamente l'endpoint specifico del dispositivo, rappresentato dal filtro dell'argomentodevices/{device-id}/messages/devicebound/#. Dopo aver stabilito la sottoscrizione, il dispositivo inizierà a ricevere i messaggi da cloud a dispositivo che gli sono stati inviati dopo la sottoscrizione. Se il dispositivo si connette con il flag CleanSession impostato su 0, la sottoscrizione sarà mantenuta tra sessioni diverse. In questo caso, alla connessione successiva con CleanSession 0 il dispositivo riceverà i messaggi in sospeso che gli sono stati inviati mentre era disconnesso. Se tuttavia il dispositivo usa il flag CleanSession impostato su 1, non riceve alcun messaggio da hub IoT finché non sottoscrive l'endpoint del dispositivo.

L'hub IoT recapita i messaggi con il Nome argomento devices/{device-id}/messages/devicebound/ o devices/{device-id}/messages/devicebound/{property-bag} in presenza di proprietà dei messaggi. {property-bag} contiene coppie chiave/valore con codifica URL di proprietà dei messaggi. Solo le proprietà dell'applicazione e le proprietà di sistema configurabili dall'utente, ad esempio messageId o correlationId, sono incluse nel contenitore delle proprietà. I nomi delle proprietà di sistema hanno il prefisso $. Le proprietà dell'applicazione usano il nome della proprietà originale senza il prefisso. Per altre informazioni sul formato del contenitore delle proprietà, vedere Invio di messaggi da dispositivo a cloud.

Nei messaggi da cloud a dispositivo i valori nel contenitore delle proprietà sono rappresentati come nella tabella seguente:

Valore proprietà Rappresentazione Descrizione
null key Solo la chiave viene visualizzata nel contenitore delle proprietà
stringa vuota key= Chiave seguita da un segno di uguale senza valore
valore non null, nonempty key=value Chiave seguita da un segno di uguale e dal valore

Nell'esempio seguente viene illustrato un contenitore delle proprietà che contiene tre proprietà dell'applicazione: prop1 con il valore null; prop2, una stringa vuota (""); e prop3 con un valore di "stringa".

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

Quando un'app del dispositivo esegue una sottoscrizione a un argomento con QoS 2, l'hub IoT concede il livello QoS 1 massimo nel pacchetto SUBACK. Successivamente, l'hub IoT invierà i messaggi al dispositivo tramite QoS 1.

Recupero delle proprietà dei dispositivi gemelli

Un dispositivo effettua la sottoscrizione a $iothub/twin/res/# per ricevere le risposte dell'operazione. Invia quindi un messaggio vuoto all'argomento $iothub/twin/GET/?$rid={request id}, con un valore popolato per request ID. Il servizio invierà quindi un messaggio di risposta con i dati del dispositivo gemello nell'argomento $iothub/twin/res/{status}/?$rid={request-id}, usando lo stesso request ID della richiesta.

L'ID richiesta può essere qualsiasi valore valido per un valore della proprietà del messaggio e lo stato viene convalidato come numero intero. Per altre informazioni, vedere Inviare messaggi da dispositivo a cloud e da cloud a dispositivo con hub IoT.

Il corpo della risposta contiene la sezione delle proprietà del dispositivo gemello, come illustrato nell'esempio di risposta seguente:

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

I possibili codici di stato sono i seguenti:

Stato Descrizione
200 Riuscita
429 Troppe richieste (limitate). Per altre informazioni, vedere hub IoT limitazione
5** Errori del server

Per altre informazioni, vedere Comprendere e usare dispositivi gemelli nell'hub IoT.

Aggiornare le proprietà segnalate di un dispositivo gemello

Per aggiornare le proprietà segnalate, il dispositivo invia una richiesta all'hub IoT tramite una pubblicazione su un argomento MQTT designato. Dopo hub IoT l'elaborazione della richiesta, risponde allo stato di esito positivo o negativo dell'operazione di aggiornamento tramite una pubblicazione a un altro argomento. Il dispositivo può sottoscrivere questo argomento per notificare il risultato della richiesta di aggiornamento del dispositivo gemello. Per implementare questo tipo di interazione di richiesta/risposta in MQTT, viene usato il concetto di ID richiesta ($rid) fornito inizialmente dal dispositivo nella richiesta di aggiornamento. L'ID richiesta è incluso anche nella risposta dell'hub IoT per consentire al dispositivo di correlare la risposta alla richiesta appropriata.

La sequenza seguente descrive in che modo un dispositivo aggiorna le proprietà dichiarate in un dispositivo gemello nell'hub IoT:

  1. Un dispositivo deve prima sottoscrivere l'argomento $iothub/twin/res/# per ricevere le risposte dell'operazione dall'hub IoT.

  2. Un dispositivo invia un messaggio che contiene l'aggiornamento di un dispositivo gemello per l'argomento $iothub/twin/PATCH/properties/reported/?$rid={request-id}. Questo messaggio include un valore request ID.

  3. Il servizio invia un messaggio di risposta che contiene il nuovo valore ETag per la raccolta di proprietà dichiarate sull'argomento $iothub/twin/res/{status}/?$rid={request-id}. Questo messaggio di risposta usa lo stesso request ID della richiesta.

Il corpo del messaggio di richiesta contiene un documento JSON che contiene nuovi valori per le proprietà segnalate. Ogni membro nel documento JSON aggiorna o aggiunge il membro corrispondente nel documento del dispositivo gemello. Un membro impostato per null eliminare il membro dall'oggetto contenitore. Ad esempio:

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

I possibili codici di stato sono i seguenti:

Stato Descrizione
204 Operazione riuscita (non viene restituito alcun contenuto)
400 Richiesta non valida. JSON non valido
429 Numero eccessivo di richieste (limitazione), come descritto in Limitazione dell'hub IoT
5** Errori del server

Il frammento di codice Python seguente illustra il processo di aggiornamento delle proprietà segnalate dal gemello su MQTT usando il client 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)

Al termine del processo di aggiornamento delle proprietà segnalate dal gemello nel frammento di codice precedente, il messaggio di pubblicazione di hub IoT ha l'argomento seguente: $iothub/twin/res/204/?$rid=1&$version=6, dove 204 è il codice di stato che indica l'esito positivo, $rid=1 corrisponde all'ID richiesta fornito dal dispositivo nel codice e $version corrisponde alla versione delle proprietà segnalate dei dispositivi gemelli dopo l'aggiornamento.

Per altre informazioni, vedere Comprendere e usare dispositivi gemelli nell'hub IoT.

Ricezione delle notifiche di aggiornamento delle proprietà desiderate

Quando un dispositivo è connesso, l'hub IoT invia notifiche all'argomento $iothub/twin/PATCH/properties/desired/?$version={new-version}, con il contenuto dell'aggiornamento eseguito dal back-end della soluzione. Ad esempio:

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

Come per gli aggiornamenti delle proprietà, i valori null indicano l'eliminazione del membro dell'oggetto JSON. $version Indica anche la nuova versione della sezione delle proprietà desiderate del gemello.

Importante

L'hub IoT genera notifiche di modifica solo quando i dispositivi sono connessi. Assicurarsi di implementare il flusso di riconnessione del dispositivo per mantenere la sincronizzazione delle proprietà desiderate tra l'hub IoT e l'app per dispositivo.

Per altre informazioni, vedere Comprendere e usare dispositivi gemelli nell'hub IoT.

Rispondere a un metodo diretto

Un dispositivo deve effettuare la sottoscrizione a $iothub/methods/POST/#. L'hub IoT invia le richieste di metodo all'argomento $iothub/methods/POST/{method-name}/?$rid={request-id} con un codice JSON valido o un corpo vuoto.

Per rispondere, il dispositivo invia un messaggio con un codice JSON valido o un corpo vuoto all'argomento $iothub/methods/res/{status}/?$rid={request-id}. In questo messaggio, l'ID della richiesta deve corrispondere a quello nel messaggio della richiesta, e lo stato deve essere un numero intero.

Per altre informazioni, vedere Comprendere e richiamare metodi diretti dall'hub IoT.

Passaggi successivi

Per altre informazioni sull'uso di MQTT, vedere:

Per altre informazioni sull'uso di SDK per dispositivi IoT, vedere:

Per altre informazioni sulla pianificazione della distribuzione dell'hub IoT, vedere: