Inviare e ricevere messaggi da cloud a dispositivo

L'hub IoT di Azure è un servizio completamente gestito che consente comunicazioni bidirezionali, inclusi i messaggi da cloud a dispositivo (C2D) dai back-end della soluzione a milioni di dispositivi.

Il presente articolo descrive come utilizzare gli SDK di Azure IoT per compilare i seguenti tipi di applicazioni:

  • Applicazioni per dispositivi che ricevono e gestiscono messaggi da cloud a dispositivo da una coda di messaggistica dell'hub IoT.

  • Applicazioni back-end che inviano messaggi da cloud a dispositivo a un singolo dispositivo tramite una coda di messaggistica dell'hub IoT.

Il presente articolo è destinato a integrare gli esempi di SDK eseguibili a cui si fa riferimento al suo interno.

Nota

Le funzionalità descritte in questo articolo 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.

Panoramica

Affinché un'applicazione del dispositivo riceva i messaggi da cloud a dispositivo, deve connettersi all'hub IoT, quindi configurare un gestore di messaggi per l'elaborazione dei messaggi in arrivo. Gli SDK per dispositivi dell'hub IoT di Azure forniscono classi e metodi che un dispositivo può utilizzare per ricevere e gestire i messaggi dal servizio. Il presente articolo illustra gli elementi chiave di qualsiasi applicazione del dispositivo che riceve messaggi, tra cui:

  • Dichiarare un oggetto client del dispositivo
  • Connettersi all'hub IoT
  • Recuperare messaggi dalla relativa coda dell'hub IoT
  • Elaborare il messaggio e inviare un acknowledgement all'hub IoT
  • Configurare un criterio di ripetizione di ricezione dei messaggi

Affinché un'applicazione back-end invii messaggi da cloud a dispositivo, deve connettersi a un hub IoT e inviare i messaggi tramite la relativa coda dell'hub IoT. Gli SDK del servizio hub IoT di Azure forniscono classi e metodi che un'applicazione può sfruttare per inviare messaggi ai dispositivi. Il presente articolo illustra gli elementi chiave di qualsiasi applicazione che invia messaggi ai dispositivi, tra cui:

  • Dichiarare un oggetto client del servizio
  • Connettersi all'hub IoT
  • Compilare e inviare il messaggio
  • Ricevere feedback di recapito
  • Configurare un criterio di ripetizione di invio dei messaggi

Informazioni sulla coda dei messaggi

Per comprendere la messaggistica da cloud a dispositivo, è importante approfondire alcuni concetti fondamentali sul funzionamento delle code dei messaggi dei dispositivi dell'hub IoT.

I messaggi da cloud a dispositivo inviati da un'applicazione back-end della soluzione a un dispositivo IoT vengono instradati tramite l'hub IoT. Non esiste alcuna comunicazione diretta di messaggistica peer-to-peer tra l'applicazione back-end della soluzione e il dispositivo di destinazione. L'hub IoT inserisce i messaggi in arrivo nella coda relativa, affinché siano pronti per essere scaricati dai dispositivi IoT di destinazione.

Per garantire il recapito di almeno un messaggio, l'hub IoT salva in modo permanente i messaggi da cloud a dispositivo nelle code dei singoli dispositivi. Prima che l'hub IoT rimuova il messaggio dalla coda, i dispositivi devono confermare in modo esplicito il completamento di un messaggio. Questo approccio garantisce la resilienza rispetto a errori di connettività e del dispositivo.

Quando l'hub IoT inserisce un messaggio in una coda di messaggi del dispositivo, imposta lo stato del messaggio su Accodato. Quando un thread del dispositivo accetta un messaggio dalla coda, l'hub IoT lo blocca impostando lo stato del messaggio su Invisibile. Questo stato impedisce ad altri thread nel dispositivo di elaborare lo stesso messaggio. Quando un thread del dispositivo completa correttamente l'elaborazione di un messaggio, invia una notifica all'hub IoT e quindi quest'ultimo imposta lo stato del messaggio su Completato.

Un'applicazione del dispositivo che riceve ed elabora correttamente un messaggio si dice che Completa il messaggio. Tuttavia, se necessario, un dispositivo può anche:

  • Rifiutare il messaggio. In questo caso, l'hub IoT ne imposta lo stato su Non recapitabile. I dispositivi che si connettono tramite il protocollo MQTT (Message Queue Telemetry Transport) non possono rifiutare i messaggi da cloud a dispositivo.
  • Abbandonare il messaggio. In questo caso, l'hub IoT inserisce di nuovo il messaggio nella coda con lo stato impostato su Accodato. I dispositivi che si connettono tramite il protocollo MQTT non possono rifiutare i messaggi da cloud a dispositivo.

Per altre informazioni sul ciclo di vita dei messaggi da cloud a dispositivo e sul modo in cui l'hub IoT elabora i messaggi da cloud a dispositivo, vedere Inviare messaggi da cloud a dispositivo da un hub IoT.

Ricezione di messaggi da cloud a dispositivo

La sezione seguente descrive come ricevere messaggi da cloud a dispositivo utilizzando la classe DeviceClient in Azure IoT SDK per .NET.

Esistono due opzioni che un'applicazione client del dispositivo può usare per la ricezione dei messaggi:

  • Polling: l'applicazione del dispositivo verifica la presenza di nuovi messaggi dell'hub IoT usando un ciclo di codice, ad esempio un ciclo while o for. Il ciclo viene eseguito continuamente, verificando la presenza di messaggi.
  • Callback: l'applicazione del dispositivo configura un metodo del gestore di messaggi asincrono che viene chiamato immediatamente all'arrivo di un messaggio.

Dichiarare un oggetto DeviceClient

DeviceClient include metodi e proprietà necessari per ricevere i messaggi dall'hub IoT.

Ad esempio:

static DeviceClient deviceClient;

Specificare i parametri di connessione

Specificare la stringa di connessione primaria dell'hub IoT e l'ID dispositivo a DeviceClient utilizzando il metodo CreateFromConnectionString. Oltre alla stringa di connessione primaria dell'hub IoT necessaria, è possibile eseguire l'overload del metodo CreateFromConnectionString per includere questi parametri facoltativi:

  • transportType: Protocollo di trasporto include varianti della versione HTTP 1, AMQP o MQTT. AMQP è l'impostazione predefinita. Per visualizzare tutti i valori disponibili, vedere TransportType Enum.
  • transportSettings: interfaccia usata per definire varie impostazioni specifiche del trasporto per DeviceClient e ModuleClient. Per altre informazioni, vedere Interfaccia ITransportSettings.
  • ClientOptions: opzioni che consentono la configurazione dell'istanza client del dispositivo o del modulo durante l'inizializzazione.

Questo esempio chiama CreateFromConnectionString per definire le impostazioni dell'hub IoT e dell'ID dispositivo della connessione DeviceClient.

static string connectionString = "{your IoT hub connection string}";
static string deviceID = "{your device ID}";
deviceClient = DeviceClient.CreateFromConnectionString(connectionString,deviceID);

Polling

Il polling utilizza ReceiveAsync per verificare la presenza di messaggi.

Una chiamata a ReceiveAsync può assumere queste forme:

  • ReceiveAsync(): attendere il periodo di timeout predefinito per un messaggio prima di continuare.
  • ReceiveAsync (Timespan): ricevere un messaggio dalla coda del dispositivo usando un timeout specifico.
  • ReceiveAsync (CancellationToken): ricevere un messaggio dalla coda del dispositivo utilizzando un token di annullamento. Quando si usa un token di annullamento, il periodo di timeout predefinito non viene utilizzato.

Quando si utilizza un tipo di trasporto HTTP 1 anziché MQTT o AMQP, il metodo ReceiveAsync verrà restituito immediatamente. Il modello supportato per i messaggi da cloud a dispositivo con HTTP 1 è rappresentato da dispositivi collegati in modo intermittente che controllano raramente la presenza di messaggi (almeno ogni 25 minuti). La generazione di altre ricezioni HTTP 1 comporta la limitazione delle richieste da parte dell'hub IoT. Per altre informazioni sulle differenze tra il supporto di MQTT, AMQP e HTTP 1, vedere Indicazioni sulle comunicazioni da cloud a dispositivo e Scegliere un protocollo di comunicazione.

Metodo CompleteAsync

Dopo che il dispositivo riceve un messaggio, l'applicazione del dispositivo chiama il metodo CompleteAsync per notificare all'hub IoT che il messaggio è stato elaborato correttamente e che pertanto può essere rimosso in modo sicuro dalla coda dei dispositivi dell'hub IoT. Il dispositivo deve chiamare questo metodo quando l'elaborazione viene completata correttamente, indipendentemente dal protocollo di trasporto in uso.

Abbandono, rifiuto o timeout del messaggio

Con i protocolli AMQP e HTTP versione 1, ma non con il protocollo MQTT, il dispositivo può anche:

  • Abbandonare un messaggio chiamando AbandonAsync. Ciò fa sì che l'hub IoT mantenga il messaggio nella coda del dispositivo per un uso futuro.
  • Rifiutare un messaggio chiamando RejectAsync. In questo modo, il messaggio viene rimosso definitivamente dalla coda del dispositivo.

Se si verifica un evento che impedisce al dispositivo di completare, abbandonare o rifiutare il messaggio, l'hub IoT, dopo un periodo di timeout fisso, accoda nuovamente il messaggio per il recapito. Per questa ragione, la logica di elaborazione del messaggio nell'app per dispositivo deve essere idempotente, in modo che la ricezione dello stesso messaggio più volte produca lo stesso risultato.

Per altre informazioni sul ciclo di vita dei messaggi da cloud a dispositivo e sul modo in cui l'hub IoT elabora i messaggi da cloud a dispositivo, vedere Inviare messaggi da cloud a dispositivo da un hub IoT.

Ciclo di polling

Utilizzando il polling, un'applicazione usa un ciclo di codice che chiama ripetutamente il metodo ReceiveAsync per verificare la presenza di nuovi messaggi, fino a quando non viene interrotto.

Se si usa ReceiveAsync con un valore di timeout o il timeout predefinito, nel ciclo ogni chiamata a ReceiveAsync attende il periodo di timeout specificato. Se si verifica il timeout di ReceiveAsync, viene restituito un valore null e il ciclo continua.

Quando viene ricevuto un messaggio, viene restituito un oggetto Attività da ReceiveAsync che deve essere passato a CompleteAsync. Una chiamata a CompleteAsync notifica all'hub IoT di eliminare il messaggio specificato dalla relativa coda in base al parametro Task.

In questo esempio, il ciclo chiama ReceiveAsync finché non si riceve un messaggio o il ciclo di polling viene interrotto.

static bool stopPolling = false;

while (!stopPolling)
{
   // Check for a message. Wait for the default DeviceClient timeout period.
   using Message receivedMessage = await _deviceClient.ReceiveAsync();

   // Continue if no message was received
   if (receivedMessage == null)
   {
      continue;
   }
   else  // A message was received
   {
      // Print the message received
      Console.WriteLine($"{DateTime.Now}> Polling using ReceiveAsync() - received message with Id={receivedMessage.MessageId}");
      PrintMessage(receivedMessage);

      // Notify IoT Hub that the message was received. IoT Hub will delete the message from the message queue.
      await _deviceClient.CompleteAsync(receivedMessage);
      Console.WriteLine($"{DateTime.Now}> Completed C2D message with Id={receivedMessage.MessageId}.");
   }

   // Check to see if polling loop should end
   stopPolling = ShouldPollingstop ();
}

Richiamata

Per ricevere messaggi da cloud a dispositivo di callback nell'applicazione del dispositivo, quest'ultima deve connettersi all'hub IoT e configurare un listener di callback per l'elaborazione dei messaggi in arrivo. I messaggi in arrivo al dispositivo vengono ricevuti dalla relativa coda dell'hub IoT.

Usando il callback, l'applicazione del dispositivo configura un metodo del gestore di messaggi tramite SetReceiveMessageHandlerAsync. Il gestore di messaggi viene chiamato, quindi viene ricevuto un messaggio. La creazione di un metodo di callback per ricevere messaggi rimuove la necessità di eseguire continuamente il polling dei messaggi ricevuti.

Il callback è disponibile solo utilizzando questi protocolli:

  • Mqtt
  • Mqtt_WebSocket_Only
  • Mqtt_Tcp_Only
  • Amqp
  • Amqp_WebSocket_Only
  • Amqp_Tcp_only

L'opzione di protocollo Http1 non supporta i callback perché i metodi SDK devono eseguire comunque il polling dei messaggi ricevuti, vanificando il principio di callback.

In questo esempio, SetReceiveMessageHandlerAsync configura un metodo del gestore di callback denominato OnC2dMessageReceivedAsync, che viene chiamato ogni volta che viene ricevuto un messaggio.

// Subscribe to receive C2D messages through a callback (which isn't supported over HTTP).
await deviceClient.SetReceiveMessageHandlerAsync(OnC2dMessageReceivedAsync, deviceClient);
Console.WriteLine($"\n{DateTime.Now}> Subscribed to receive C2D messages over callback.");

Criteri di ripetizione di ricezione dei messaggi

I criteri di ripetizione del messaggio client del dispositivo possono essere definiti usando DeviceClient.SetRetryPolicy.

Il timeout di ripetizione del messaggio viene salvato nella proprietà DeviceClient.OperationTimeoutInMilliseconds.

Esempio di messaggio di ricezione dell'SDK

L'SDK .NET/C# include un esempio di ricezione messaggi che include i metodi di ricezione descritti in questa sezione.

Invio di messaggi da cloud a dispositivo

Questa sezione descrive il codice essenziale per inviare un messaggio da un'applicazione back-end della soluzione a un dispositivo IoT mediante la classe ServiceClient nell'SDK Azure IoT per .NET. Come illustrato in precedenza, un'applicazione back-end della soluzione si connette a un hub IoT e i messaggi vengono inviati all'hub IoT codificato con un dispositivo di destinazione. L'hub IoT archivia i messaggi in arrivo nella coda relativa e questi vengono recapitati dalla coda dei messaggi dell'hub IoT al dispositivo di destinazione.

Un'applicazione back-end della soluzione può anche richiedere e ricevere feedback sul recapito per un messaggio inviato all'hub IoT destinato al recapito dei dispositivi tramite la coda di messaggi.

Dichiarare un oggetto ServiceClient

ServiceClient include metodi e proprietà necessari per l'invio di messaggi da un'applicazione tramite l'hub IoT a un dispositivo.

static ServiceClient serviceClient;

Specificare la stringa di connessione

Specificare la stringa di connessione primaria dell'hub IoT al ServiceClient usando il metodo CreateFromConnectionString. Oltre alla stringa di connessione primaria dell'hub IoT necessaria, è possibile eseguire l'overload del metodo CreateFromConnectionString per includere questi parametri facoltativi:

  • transportType - Amqp o Amqp_WebSocket_Only.
  • transportSettings: le impostazioni proxy AMQP e HTTP per il client del servizio.
  • ServiceClientOptions: le opzioni che consentono la configurazione dell'istanza client del servizio durante l'inizializzazione. Per altre informazioni, vedere ServiceClientOptions.

Questo esempio crea l'oggetto ServiceClient utilizzando la stringa di connessione dell'hub IoT.

static string connectionString = "{your iot hub connection string}";
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);

Inviare un messaggio asincrono da cloud a dispositivo

Usare sendAsync per inviare un messaggio asincrono da un'applicazione tramite il cloud (hub IoT) al dispositivo. La chiamata viene effettuata usando il protocollo AMQP.

sendAsync utilizza questi parametri:

  • deviceID: l'identificatore di stringa del dispositivo di destinazione.
  • message: il messaggio da cloud a dispositivo. Il messaggio è del tipo Message e può essere formattato di conseguenza.
  • timeout: un valore di timeout facoltativo. Il valore predefinito è un minuto, se non specificato altrimenti.

Questo esempio invia un messaggio di test al dispositivo di destinazione con un valore di timeout di 10 secondi.

string targetDevice = "Device-1";
static readonly TimeSpan operationTimeout = TimeSpan.FromSeconds(10);
var commandMessage = new
Message(Encoding.ASCII.GetBytes("Cloud to device message."));
await serviceClient.SendAsync(targetDevice, commandMessage, operationTimeout);

Ricevere feedback di recapito

Un programma di invio può richiedere gli acknowledgment di recapito (o della scadenza) dall'hub IoT per ogni messaggio da cloud a dispositivo. Questa opzione consente al programma di invio di sfruttare la logica di notifica, ripetizione o compensazione. Una descrizione completa delle operazioni e delle proprietà dei feedback dei messaggi è descritta in Feedback sui messaggi.

Per ricevere feedback sul recapito dei messaggi:

  • Creare l'oggetto feedbackReceiver
  • Inviare messaggi usando il parametro Ack
  • In attesa di ricevere il feedback

Creare l'oggetto feedbackReceiver

Chiamare GetFeedbackReceiver per creare un oggetto FeedbackReceiver. FeedbackReceiver contiene metodi che i servizi possono utilizzare per eseguire operazioni di ricezione del feedback.

var feedbackReceiver = serviceClient.GetFeedbackReceiver();

Inviare messaggi usando il parametro Ack

Per ricevere feedback di recapito, ciascun messaggio deve includere un valore per la proprietà Ack di acknowledgement del recapito. La proprietà Ack può avere uno dei valori seguenti:

  • none (impostazione predefinita): non viene generato alcun messaggio di feedback.

  • Positive: ricevere un messaggio di feedback se il messaggio è stato completato.

  • Negative: ricevere un messaggio di feedback se il messaggio è scaduto (è stato raggiunto il numero massimo di recapito) senza essere stato completato dal dispositivo.

  • Full: feedback sia per i risultati Positive che per quelli Negative.

In questo esempio, la proprietà Ack è impostata su Full, richiedendo sia un feedback positivo che negativo per il recapito di un messaggio.

var commandMessage = new
Message(Encoding.ASCII.GetBytes("Cloud to device message."));
commandMessage.Ack = DeliveryAcknowledgement.Full;
await serviceClient.SendAsync(targetDevice, commandMessage);

In attesa di ricevere il feedback

Definire un oggetto CancellationToken. Quindi, in un ciclo, chiamare ripetutamente ReceiveAsync, verificando la presenza di messaggi di feedback per il recapito. Ogni chiamata a ReceiveAsync attende il periodo di timeout definito per l'oggetto ServiceClient.

  • Se un timeout ReceiveAsync scade senza messaggi ricevuti, ReceiveAsync restituisce null e il ciclo continua.
  • Se viene ricevuto un messaggio di feedback, viene restituito un oggetto Attività da ReceiveAsync che deve essere passato a CompleteAsync insieme al token di annullamento. Una chiamata a CompleteAsync elimina il messaggio inviato specificato dalla relativa coda in base al parametro Task.
  • Se necessario, il codice di ricezione può chiamare AbandonAsync per reinserire un messaggio di invio nella coda.
var feedbackReceiver = serviceClient.GetFeedbackReceiver();
// Define the cancellation token.
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
// Call ReceiveAsync, passing the token. Wait for the timout period.
var feedbackBatch = await feedbackReceiver.ReceiveAsync(token);
if (feedbackBatch == null) continue;

In questo esempio viene illustrato un metodo che include questi passaggi.

private async static void ReceiveFeedbackAsync()
{
      var feedbackReceiver = serviceClient.GetFeedbackReceiver();

      Console.WriteLine("\nReceiving c2d feedback from service");
      while (true)
      {
         // Check for messages, wait for the timeout period.
         var feedbackBatch = await feedbackReceiver.ReceiveAsync();
         // Continue the loop if null is received after a timeout.
         if (feedbackBatch == null) continue;

         Console.ForegroundColor = ConsoleColor.Yellow;
         Console.WriteLine("Received feedback: {0}",
            string.Join(", ", feedbackBatch.Records.Select(f => f.StatusCode)));
         Console.ResetColor();

         await feedbackReceiver.CompleteAsync(feedbackBatch);
      }
   }

Si noti che questo modello di ricezione del feedback è simile a quello usato per ricevere i messaggi da cloud a dispositivo nell'applicazione del dispositivo.

Riconnessione del client del servizio

In caso di eccezione, il client del servizio inoltra tali informazioni all'applicazione chiamante. A questo punto, è consigliabile esaminare i dettagli dell'eccezione e intraprendere le azioni necessarie.

Ad esempio:

  • Se si tratta di un'eccezione di rete, è possibile ripetere l'operazione.
  • Se si tratta di un'eccezione di sicurezza (eccezione non autorizzata), esaminare le credenziali e assicurarsi che siano aggiornate.
  • Se si tratta di un'eccezione di limitazione/quota superata, monitorare e/o modificare la frequenza di invio delle richieste o aggiornare l'unità di scala dell'istanza dell'hub. Per informazioni dettagliate, vedere Quote e limitazioni dell'hub IoT.

Criteri di ripetizione di invio dei messaggi

I criteri di ripetizione dei messaggi ServiceClient possono essere definiti tramite ServiceClient.SetRetryPolicy.

Esempio di messaggio di invio dell'SDK

L'SDK .NET/C# include un esempio client del servizio che comprende i metodi di invio dei messaggi descritti in questa sezione.

Ricezione di messaggi da cloud a dispositivo

Questa sezione descrive come ricevere messaggi da cloud a dispositivo utilizzando la classe DeviceClient dall'SDK di Azure IoT per Java.

Affinché un'applicazione del dispositivo basata su Java riceva i messaggi da cloud a dispositivo, deve connettersi all'hub IoT, quindi configurare un listener di callback e un gestore di messaggi per l'elaborazione dei messaggi in arrivo dall'hub IoT. L'applicazione del dispositivo deve anche essere in grado di rilevare e gestire le disconnessioni, qualora si interrompa la connessione messaggi da dispositivo a hub IoT.

Importare librerie SDK di Azure IoT per Java

Il codice a cui si fa riferimento in questo articolo utilizza queste librerie SDK.

import com.microsoft.azure.sdk.iot.device.*;
import com.microsoft.azure.sdk.iot.device.exceptions.IotHubClientException;
import com.microsoft.azure.sdk.iot.device.transport.IotHubConnectionStatus;

Dichiarare un oggetto DeviceClient

Per la creazione di un'istanza dell'oggetto DeviceClient, sono necessari questi parametri:

  • connString: la stringa di connessione del dispositivo IoT. La stringa di connessione è un set di coppie chiave-valore separate da ';', con le chiavi e i valori separati da '='. Deve contenere i valori per queste chiavi: HostName, DeviceId, and SharedAccessKey.
  • Protocollo di trasporto: la connessione DeviceClient può usare uno dei seguenti protocolli di trasporto IoTHubClientProtocol. AMQP è il più versatile, consente di controllare frequentemente i messaggi e permette di rifiutarsi o annullarli. MQTT non supporta i metodi di rifiuto o abbandono dei messaggi:
    • AMQPS
    • AMQPS_WS
    • HTTPS
    • MQTT
    • MQTT_WS

Ad esempio:

static string connectionString = "{a device connection string}";
static protocol = IotHubClientProtocol.AMQPS;
DeviceClient client = new DeviceClient(connectionString, protocol);

Impostare il metodo di callback del messaggio

Usare il metodo setMessageCallback per definire un metodo del gestore di messaggi che riceve una notifica alla ricezione di un messaggio dall'hub IoT.

setMessageCallback include questi parametri:

  • callback: nome del metodo di callback. Può essere null.
  • context: un contesto facoltativo di tipo object. Usare null, se non specificato altrimenti.

In questo esempio, un metodo callback, denominato MessageCallback e privo di parametro di contesto viene passato a setMessageCallback.

client.setMessageCallback(new MessageCallback(), null);

Creare un gestore di callback dei messaggi

Un gestore di messaggi di callback riceve ed elabora un messaggio in arrivo passato dalla coda dei messaggi dell'hub IoT.

In questo esempio, il gestore di messaggi elabora un messaggio in arrivo e quindi restituisce IotHubMessageResult.COMPLETE. Un valore restituito IotHubMessageResult.COMPLETE notifica all'hub IoT che il messaggio è stato elaborato correttamente e che può essere rimosso in modo sicuro dalla coda del dispositivo. Il dispositivo deve restituire IotHubMessageResult.COMPLETE al termine dell'elaborazione, notificando all'hub IoT che il messaggio deve essere rimosso dalla coda relativa, indipendentemente dal protocollo in uso.

  protected static class MessageCallback implements com.microsoft.azure.sdk.iot.device.MessageCallback
  {
      public IotHubMessageResult onCloudToDeviceMessageReceived(Message msg, Object context)
      {
          System.out.println(
                  "Received message with content: " + new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET));
          // Notify IoT Hub that the message
          return IotHubMessageResult.COMPLETE;
      }
  }

Opzioni di abbandono e rifiuto dei messaggi

Anche se la maggior parte dei messaggi in arrivo a un dispositivo dovrebbe essere ricevuta correttamente e generare IotHubMessageResult.COMPLETE, potrebbe essere necessario abbandonare o rifiutare un messaggio.

  • Con AMQP e HTTPS, ma non con MQTT, un'applicazione può:
    • IotHubMessageResult.ABANDON il messaggio. L'hub IoT lo accoda nuovamente e lo invia di nuovo in un secondo momento.
    • IotHubMessageResult.REJECT il messaggio. L'hub IoT non accoda nuovamente il messaggio e lo rimuove definitivamente dalla coda dei messaggi.
  • I client che utilizzano MQTT o MQTT_WS non possono ABANDON o REJECT i messaggi.

Se si verifica un evento che impedisce al dispositivo di completare, abbandonare o rifiutare il messaggio, l'hub IoT, dopo un periodo di timeout fisso, accoda nuovamente il messaggio per il recapito. Per questa ragione, la logica di elaborazione del messaggio nell'app per dispositivo deve essere idempotente, in modo che la ricezione dello stesso messaggio più volte produca lo stesso risultato.

Per altre informazioni sul ciclo di vita dei messaggi da cloud a dispositivo e sul modo in cui l'hub IoT elabora i messaggi da cloud a dispositivo, vedere Inviare messaggi da cloud a dispositivo da un hub IoT.

Nota

Se si usa HTTPS invece di MQTT o AMQP per il trasporto, l'istanza DeviceClient controlla raramente i messaggi provenienti dall'hub IoT (almeno ogni 25 minuti). Per altre informazioni sulle differenze tra il supporto di MQTT, AMQP e HTTPS, vedere Linee guida per le comunicazioni da cloud a dispositivo e Scegliere un protocollo di comunicazione.

Creare il metodo di callback dello stato del messaggio

Un'applicazione può utilizzare registerConnectionStatusChangeCallback per registrare un metodo di callback da eseguire quando lo stato della connessione del dispositivo cambia. In questo modo, l'applicazione può rilevare una connessione di messaggi inattiva e tentare la riconnessione.

In questo esempio, IotHubConnectionStatusChangeCallbackLogger viene registrato come metodo di callback di modifica dello stato della connessione.

client.registerConnectionStatusChangeCallback(new IotHubConnectionStatusChangeCallbackLogger(), new Object());

Il callback viene attivato e viene passato un oggetto ConnectionStatusChangeContext.

Chiamare connectionStatusChangeContext.getNewStatus() per ottenere lo stato di connessione corrente.

IotHubConnectionStatus status = connectionStatusChangeContext.getNewStatus();

Lo stato di connessione restituito può avere uno dei seguenti valori:

  • IotHubConnectionStatus.DISCONNECTED
  • IotHubConnectionStatus.DISCONNECTED_RETRYING
  • IotHubConnectionStatus.CONNECTED

Chiamare connectionStatusChangeContext.getNewStatusReason() per ottenere il motivo della modifica dello stato di connessione.

IotHubConnectionStatusChangeReason statusChangeReason = connectionStatusChangeContext.getNewStatusReason();

Chiamare connectionStatusChangeContext.getCause() per trovare il motivo della modifica dello stato di connessione. getCause() può restituire null se non sono disponibili informazioni.

Throwable throwable = connectionStatusChangeContext.getCause();
if (throwable != null)
    throwable.printStackTrace();

Vedere l'esempio HandleMessages elencato nella sezione dell'esempio di messaggio di ricezione dell'SDK di questo articolo per un esempio completo che illustra come estrarre lo stato della modifica dello stato di connessione del metodo di callback di modifica dello stato, il motivo per cui lo stato del dispositivo è cambiato e il relativo contesto.

Aprire la connessione tra il dispositivo e l'hub IoT

Usare open per creare una connessione tra il dispositivo e l'hub IoT. Il dispositivo può ora inviare e ricevere messaggi in modo asincrono da e verso un hub IoT. Se il client è già aperto, il metodo non esegue alcuna operazione.

client.open(true);

Esempio di messaggio di ricezione dell'SDK

HandleMessages: un'app del dispositivo di esempio inclusa nell'SDK di Microsoft Azure IoT per Java, che si connette all'hub IoT e riceve messaggi da cloud a dispositivo.

Invio di messaggi da cloud a dispositivo

Questa sezione descrive come inviare un messaggio da cloud a dispositivo utilizzando la classe ServiceClient dall'SDK di Azure IoT per Java. Un'applicazione back-end della soluzione si connette a un hub IoT e i messaggi vengono inviati all'hub IoT codificato con un dispositivo di destinazione. L'hub IoT archivia i messaggi in arrivo nella coda relativa e questi vengono recapitati dalla coda dei messaggi dell'hub IoT al dispositivo di destinazione.

Un'applicazione back-end della soluzione può anche richiedere e ricevere feedback sul recapito per un messaggio inviato all'hub IoT destinato al recapito dei dispositivi tramite la coda di messaggi.

Aggiungere l'istruzione di dipendenza

Aggiungere la dipendenza per utilizzare il pacchetto iothub-java-service-client nell'applicazione per comunicare con il servizio hub IoT:

<dependency>
  <groupId>com.microsoft.azure.sdk.iot</groupId>
  <artifactId>iot-service-client</artifactId>
  <version>1.7.23</version>
</dependency>

Aggiungere le istruzioni di importazione

Aggiungere queste istruzioni import per utilizzare l'SDK di Azure IoT per Java e il gestore eccezioni.

import com.microsoft.azure.sdk.iot.service.*;
import java.io.IOException;
import java.net.URISyntaxException;

Definire il protocollo di connessione

Utilizzare IotHubServiceClientProtocol per definire il protocollo a livello di applicazione che viene usato dal client del servizio per la comunicazione con un hub IoT.

IotHubServiceClientProtocol accetta solo l'enumerazione AMQPS o AMQPS_WS.

private static final IotHubServiceClientProtocol protocol =    
    IotHubServiceClientProtocol.AMQPS;

Creare l'oggetto ServiceClient

Creare l'oggetto ServiceClient, specificando la stringa di connessione e il protocollo dell'hub IoT.

private static final String connectionString = "{yourhubconnectionstring}";
private static final ServiceClient serviceClient (connectionString, protocol);

Aprire la connessione tra l'applicazione e l'hub IoT

Eseguire open sulla connessione del mittente AMQP. Questo metodo crea la connessione tra l'applicazione e l'hub IoT.

serviceClient.open();

Aprire un ricevitore di feedback per il recapito dei messaggi

È possibile usare un FeedbackReceiver per ricevere il recapito dei messaggi inviati al feedback dell'hub IoT. Un oggetto FeedbackReceiver è un ricevitore specializzato il cui metodo Receive restituisce FeedbackBatch anziché Message.

In questo esempio, viene creato l'oggetto FeedbackReceiver e viene chiamata l'istruzione open() per attendere il feedback.

FeedbackReceiver feedbackReceiver = serviceClient
  .getFeedbackReceiver();
if (feedbackReceiver != null) feedbackReceiver.open();

Aggiungi proprietà del messaggio

Facoltativamente, è possibile usare setProperties per aggiungere proprietà del messaggio. Queste proprietà sono incluse nel messaggio inviato al dispositivo e possono essere estratte dall'applicazione del dispositivo, al momento della ricezione.

Map<String, String> propertiesToSend = new HashMap<String, String>();
propertiesToSend.put(messagePropertyKey,messagePropertyKey);
messageToSend.setProperties(propertiesToSend);

Creare e inviare un messaggio asincrono

L'oggetto Message memorizza il messaggio da inviare. In questo esempio, viene recapitato un messaggio "Da cloud a dispositivo".

Usare setDeliveryAcknowledgement per richiedere l'acknowledgement dei messaggi recapitati/non recapitati alla coda dei messaggi dell'hub IoT. In questo esempio, l'acknowledgement richiesto è Full, recapitato o non recapitato.

Usare SendAsync per inviare un messaggio asincrono dal client al dispositivo. In alternativa, è possibile utilizzare il metodo Send (non asincrono), ma questa funzione viene sincronizzata internamente in modo che sia consentita una sola operazione di invio alla volta. Il messaggio viene recapitato dall'applicazione all'hub IoT. L'hub IoT inserisce il messaggio nella coda relativa, pronto per essere recapitato al dispositivo di destinazione.

Message messageToSend = new Message("Cloud to device message.");
messageToSend.setDeliveryAcknowledgementFinal(DeliveryAcknowledgement.Full);
serviceClient.sendAsync(deviceId, messageToSend);

Ricevere il feedback per il recapito dei messaggi

Dopo l'invio di un messaggio dall'applicazione, l'applicazione può chiamare receive con o senza un valore di timeout. Se non viene specificato un valore di timeout, viene utilizzato il timeout predefinito. In questo modo viene restituito un oggetto FeedbackBatch che contiene le proprietà di feedback sul recapito dei messaggi che è possibile esaminare.

Questo esempio crea il ricevitore FeedbackBatch e chiama getEnqueuedTimeUtc, stampando l'ora di accodamento del messaggio.

FeedbackBatch feedbackBatch = feedbackReceiver.receive(10000);
if (feedbackBatch != null) {
  System.out.println("Message feedback received, feedback time: "
    + feedbackBatch.getEnqueuedTimeUtc().toString());
}

Esempi di messaggi di invio SDK

Installare la libreria SDK di Azure IoT

Installare la libreria SDK azure-iot-device nel computer di sviluppo prima di chiamare qualsiasi codice correlato:

pip install azure-iot-device

Esistono due classi SDK Python utilizzate per l'invio di messaggi da e verso dispositivi IoT. I metodi di gestione dei messaggi di queste classi sono descritti nelle sezioni di questa pagina.

  • La classe IoTHubDeviceClient include metodi per creare una connessione sincrona da un dispositivo a un hub IoT di Azure e per ricevere messaggi dall'hub IoT.

  • La classe IoTHubRegistryManager include le API per le operazioni di gestore registro dell'hub IoT. In questo articolo i metodi di questa classe illustrano come connettersi all'hub IoT e inviare un messaggio a un dispositivo.

Ricezione di messaggi da cloud a dispositivo

Questa sezione descrive come ricevere messaggi da cloud a dispositivo usando la classe IoTHubDeviceClient dall'SDK di Azure IoT per Python.

Affinché un'applicazione del dispositivo basata su Python riceva i messaggi da cloud a dispositivo, deve connettersi all'hub IoT, quindi configurare un gestore di messaggi di callback per l'elaborazione dei messaggi in arrivo dall'hub IoT.

Importare l'oggetto IoTHubDeviceClient

Aggiungere una riga di codice per importare le funzioni IoTHubDeviceClient dall'SDK azure.iot.device.

from azure.iot.device import IoTHubDeviceClient

Connettere il client del dispositivo

Creare un'istanza di IoTHubDeviceClientpassando una stringa di connessione dell'hub IoT a create_from_connection_string. Verrà creata una connessione dal dispositivo all'hub IoT.

In alternativa, è possibile connettere IoTHubDeviceClient a un dispositivo usando uno di questi metodi:

deviceConnectionString = "{your IoT hub connection string}";
client = IoTHubDeviceClient.create_from_connection_string ({deviceConnectionString})

Gestire la riconnessione

Per impostazione predefinita, IoTHubDeviceClient tenta di ristabilire una connessione interrotta. Il comportamento di riconnessione è regolato dai parametri IoTHubDeviceClient connection_retry e connection_retry_interval.

Creare un gestore di messaggi

Creare la funzione del gestore di messaggi per l'elaborazione dei messaggi in arrivo nel dispositivo.

In questo esempio, viene chiamato message_handler alla ricezione di un messaggio. Le proprietà del messaggio (.items) vengono stampate nella console mediante un ciclo.

def message_handler(message):
    global RECEIVED_MESSAGES
    RECEIVED_MESSAGES += 1
    print("")
    print("Message received:")

    # print data from both system and application (custom) properties
    for property in vars(message).items():
        print ("    {}".format(property))

    print("Total calls received: {}".format(RECEIVED_MESSAGES))

Assegnare il gestore di messaggi

Utilizzare il metodo on_message_received per assegnare il metodo del gestore di messaggi all'oggetto IoTHubDeviceClient.

In questo esempio, viene associato un metodo del gestore di messaggi denominato message_handler all'oggetto IoTHubDeviceClient client. L'oggetto client attende di ricevere un messaggio da cloud a dispositivo da un hub IoT. Questo codice attende fino a 300 secondi (5 minuti) per un messaggio o esce, se viene premuto un tasto della tastiera.

try:
    # Attach the handler to the client
    client.on_message_received = message_handler

    while True:
        time.sleep(300)
except KeyboardInterrupt:
    print("IoT Hub C2D Messaging device sample stopped")
finally:
    # Graceful exit
    print("Shutting down IoT Hub Client")
    client.shutdown()

Esempio di messaggio di ricezione dell'SDK

Ricezione messaggio: ricevere messaggi da cloud a dispositivo (C2D) inviati dall'hub IoT di Azure a un dispositivo.

Invio di messaggi da cloud a dispositivo

Questa sezione descrive come inviare un messaggio da cloud a dispositivo usando la classe IoTHubRegistryManager dell'SDK di Azure IoT per Python. Un'applicazione back-end della soluzione si connette a un hub IoT e i messaggi vengono inviati all'hub IoT codificato con un dispositivo di destinazione. L'hub IoT archivia i messaggi in arrivo nella coda relativa e questi vengono recapitati dalla coda dei messaggi dell'hub IoT al dispositivo di destinazione.

Importare l'oggetto IoTHubRegistryManager

Aggiungere l'istruzione import seguente. IoTHubRegistryManager include le API per le operazioni di gestore registro dell'hub IoT.

from azure.iot.hub import IoTHubRegistryManager

Connettere il gestore registro dell'hub IoT

Creare un'istanza dell'oggetto IoTHubRegistryManager che si connette a un hub IoT, passando una stringa di connessione dell'hub IoT a from_connection_string.

IoTHubConnectionString = "{Primary connection string to an IoT hub}"
registry_manager = IoTHubRegistryManager.from_connection_string(IoTHubConnectionString)

Compilare e inviare un messaggio

Usare send_c2d_message per inviare un messaggio tramite il cloud (hub IoT) al dispositivo.

send_c2d_message utilizza questi parametri:

  • deviceID: l'identificatore di stringa del dispositivo di destinazione.
  • message: il messaggio da cloud a dispositivo. Il messaggio è di tipo str (stringa).
  • properties: una raccolta facoltativa di proprietà di tipo dict. Le proprietà possono contenere quelle dell'applicazione e quelle di sistema. Il valore predefinito è {}.

Questo esempio invia un messaggio di test al dispositivo di destinazione.

# define the device ID
deviceID = "Device-1"

# define the message
message = "{\"c2d test message\"}"

# include optional properties
props={}
props.update(messageId = "message1")
props.update(prop1 = "test property-1")
props.update(prop1 = "test property-2")
prop_text = "Test message"
props.update(testProperty = prop_text)

# send the message through the cloud (IoT Hub) to the device
registry_manager.send_c2d_message(deviceID, message, properties=props)

Esempio di messaggio di invio dell'SDK

send_message.py: illustra come inviare un messaggio da cloud a dispositivo.

Installare i pacchetti di messaggistica Node.js

Eseguire questi comandi per installare i pacchetti azure-iot-device e azure-iothub nel computer di sviluppo:

npm install azure-iot-device --save
npm install azure-iothub --save

Il pacchetto azure-iot-device contiene oggetti che si interfacciano con i dispositivi IoT. Questo articolo descrive il codice di classe Client che riceve messaggi dall'hub IoT.

Il pacchetto azure-iothub contiene oggetti che si interfacciano con l'hub IoT. Questo articolo descrive il codice di classe Client che invia un messaggio da un'applicazione a un dispositivo tramite l'hub IoT.

Ricevere messaggi nell'applicazione del dispositivo

Questa sezione descrive come ricevere messaggi da cloud a dispositivo usando il pacchetto azure-iot-device nell'SDK di Azure IoT per Node.js.

Affinché un'applicazione del dispositivo basata su Node.js riceva i messaggi da cloud a dispositivo, deve connettersi all'hub IoT, quindi configurare un listener di callback e un gestore di messaggi per l'elaborazione dei messaggi in arrivo dall'hub IoT. L'applicazione del dispositivo deve anche essere in grado di rilevare e gestire le disconnessioni, qualora si interrompa la connessione messaggi da dispositivo a hub IoT.

Creare un modulo client

Dal pacchetto azure-iot-device, creare un oggetto Client usando la classe Client. La classe Client contiene metodi che un dispositivo può utilizzare per ricevere e inviare all'hub IoT.

const Client = require('azure-iot-device').Client;

Scegliere un protocollo di trasporto

L'oggetto Client supporta i protocolli seguenti:

  • Amqp
  • Http: quando si usa Http, l'istanza Client verifica con scarsa frequenza la presenza di messaggi provenienti dall'hub IoT (almeno ogni 25 minuti).
  • Mqtt
  • MqttWs
  • AmqpWs

Per altre informazioni sulle differenze tra il supporto di MQTT, AMQP e HTTPS, vedere Linee guida per le comunicazioni da cloud a dispositivo e Scegliere un protocollo di comunicazione.

In questo esempio, il protocollo AMQP viene assegnato a una variabile Protocol. Questa variabile Protocol viene passata al metodo Client.fromConnectionString nella sezione Aggiungere la stringa di connessione di questo articolo.

const Protocol = require('azure-iot-device-mqtt').Amqp;

Funzionalità di completamento, rifiuto e abbandono dei messaggi

I metodi di completamento, rifiuto e abbandono dei messaggi possono essere utilizzati a seconda del protocollo scelto.

AMQP e HTTP

I trasporti AMQP e HTTP possono completare, rifiutare o abbandonare un messaggio:

  • Completa: per completare un messaggio, il servizio che ha inviato il messaggio da cloud a dispositivo riceve una notifica per la ricezione del messaggio. L'hub IoT rimuove il messaggio dalla relativa coda. Il metodo assume la forma di client.complete(message, callback function).
  • Rifiuta: per rifiutare un messaggio, il servizio che ha inviato il messaggio da cloud a dispositivo riceve una notifica che indica che il messaggio non viene elaborato dal dispositivo. L'hub IoT rimuove definitivamente il messaggio dalla relativa coda. Il metodo assume la forma di client.reject(message, callback function).
  • Abbandono: per abbandonare un messaggio, l'hub IoT tenta immediatamente di inviarlo nuovamente. L'hub IoT mantiene il messaggio nella coda del dispositivo per un consumo futuro. Il metodo assume la forma di client.abandon(message, callback function).
MQTT

MQTT non supporta funzioni di completamento, di rifiuto o di abbandono del messaggio. Invece, MQTT accetta un messaggio per impostazione predefinita e questo viene rimosso dalla coda dei messaggi dell'hub IoT.

Tentativi di nuovo recapito

Se si verifica un evento che impedisce al dispositivo di completare, abbandonare o rifiutare il messaggio, l'hub IoT, dopo un periodo di timeout fisso, accoda nuovamente il messaggio per il recapito. Per questa ragione, la logica di elaborazione del messaggio nell'app per dispositivo deve essere idempotente, in modo che la ricezione dello stesso messaggio più volte produca lo stesso risultato.

Aggiungere la stringa e il protocollo di trasporto dell'hub IoT

Chiamare fromConnectionString per stabilire una connessione da dispositivo a hub IoT mediante questi parametri:

  • connStr: stringa di connessione che incapsula le autorizzazioni "device connect" per un hub IoT. La stringa di connessione contiene nome host, ID dispositivo e chiave di accesso condiviso nel formato seguente: "HostName=<iothub_host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"
  • transportCtor: protocollo di trasporto.
const Protocol = require('azure-iot-device-mqtt').Amqp;
let client = Client.fromConnectionString(deviceConnectionString, Protocol);

Creare un gestore di messaggi in arrivo

Il gestore di messaggi viene chiamato per ogni messaggio in arrivo.

Dopo la ricezione di un messaggio, se si usa il trasporto HTTP o AMQP, chiamare il metodo client.complete per informare l'hub IoT che il messaggio può essere rimosso dalla relativa coda.

Ad esempio, questo gestore di messaggi stampa l'ID messaggio e il corpo del messaggio nella console, quindi chiama client.complete per notificare all'hub IoT che ha elaborato il messaggio e che questo può essere rimosso in modo sicuro dalla coda del dispositivo. La chiamata a complete non è necessaria se si utilizza il trasporto MQTT, pertanto può essere omessa. È necessaria una chiamata a complete per il trasporto AMQP o HTTPS.

function messageHandler(msg) {
  console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
  client.complete(msg, printResultFor('completed'));
}

Creare un gestore di disconnessione della connessione

Il gestore di disconnessione viene chiamato quando la connessione viene disconnessa. Un gestore di disconnessione è utile per implementare il codice di riconnessione.

Questo esempio rileva e visualizza il messaggio di errore di disconnessione nella console.

function disconnectHandler() {
  clearInterval(sendInterval);
  sendInterval = null;
  client.open().catch((err) => {
    console.error(err.message);
  });
}

Aggiungere listener di eventi

È possibile specificare questi listener di eventi usando il metodo .on.

  • Gestore connessione
  • Gestore degli errori
  • Gestore disconnessione
  • Gestore di messaggi

Questo esempio include i gestori di messaggi e disconnessione definiti in precedenza.

client.on('connect', connectHandler);
client.on('error', errorHandler);
client.on('disconnect', disconnectHandler);
client.on('message', messageHandler);

Aprire la connessione all'hub IoT

Usare il metodo open per aprire una connessione tra un dispositivo IoT e l'hub IoT. Utilizzare .catch(err) per rilevare un errore e il codice del gestore di chiamata.

Ad esempio:

client.open()
.catch((err) => {
  console.error('Could not connect: ' + err.message);
});

Esempio di messaggio di ricezione dell'SDK

simple_sample_device: un'app per dispositivi che si connette all'hub IoT e riceve messaggi da cloud a dispositivo.

Invio di messaggi da cloud a dispositivo

Questa sezione descrive come inviare un messaggio da cloud a dispositivo usando il pacchetto azure-iothub dall'SDK di Azure IoT per Node.js. Come illustrato in precedenza, un'applicazione back-end della soluzione si connette a un hub IoT e i messaggi vengono inviati all'hub IoT codificato con un dispositivo di destinazione. L'hub IoT archivia i messaggi in arrivo nella coda relativa e questi vengono recapitati dalla coda dei messaggi dell'hub IoT al dispositivo di destinazione.

Un'applicazione back-end della soluzione può anche richiedere e ricevere feedback sul recapito per un messaggio inviato all'hub IoT destinato al recapito dei dispositivi tramite la coda di messaggi.

Caricare i moduli client e messaggio

Dichiarare un oggetto Client usando la classe Client del pacchetto azure-iothub.

Dichiarare un oggetto Message usando la classe Message del pacchetto azure-iot-common.

'use strict';
var Client = require('azure-iothub').Client;
var Message = require('azure-iot-common').Message;

Creare l'oggetto Client

Creare il Client tramite fromConnectionString usando i seguenti parametri:

  • Stringa di connessione dell'hub IoT
  • Tipo di trasporto

In questo esempio, l'oggetto serviceClient viene creato con il tipo di trasporto Amqp.

var connectionString = '{IoT Hub connection string}';
var serviceClient = Client.fromConnectionString(connectionString,`Amqp`);

Aprire la connessione client

Chiamare il metodo Client open per aprire una connessione tra un'applicazione e l'hub IoT.

open può essere chiamato con o senza specificare una funzione di richiamata chiamata al completamento dell'operazione open.

In questo esempio, il metodo open include una funzione di richiamata di connessione aperta facoltativa err. Se si verifica un errore di apertura, viene restituito un oggetto di errore. Se la connessione aperta ha esito positivo, viene restituito un valore di callback null.

serviceClient.open(function (err)
if (err)
  console.error('Could not connect: ' + err.message);

Creare un messaggio

L'oggetto message include il messaggio asincrono da cloud a dispositivo. La funzionalità del messaggio opera allo stesso modo su AMQP, MQTT e HTTP.

L'oggetto messaggio supporta diverse proprietà, incluse queste. Per un elenco completo, vedere le proprietà del messaggio.

  • ack: feedback di recapito. Descritto nella sezione successiva.
  • properties: mappa contenente chiavi stringa e valori per il salvataggio delle proprietà personalizzate del messaggio.
  • messageId: usato per correlare la comunicazione bidirezionale.

Aggiungere il corpo del messaggio quando viene creata un'istanza dell'oggetto messaggio. In questo esempio viene aggiunto un messaggio 'Cloud to device message.'.

var message = new Message('Cloud to device message.');
message.ack = 'full';
message.messageId = "My Message ID";

Acknowledgement di recapito

Un programma di invio può richiedere gli acknowledgment di recapito (o della scadenza) dall'hub IoT per ogni messaggio da cloud a dispositivo. Questa opzione consente al programma di invio di sfruttare la logica di notifica, ripetizione o compensazione. Una descrizione completa delle operazioni e delle proprietà dei feedback dei messaggi è descritta in Feedback sui messaggi.

Ogni messaggio che deve ricevere il feedback dei messaggi deve includere un valore per la proprietà ack di acknowledgement del recapito. La proprietà ack può avere uno dei valori seguenti:

  • none (impostazione predefinita): non viene generato alcun messaggio di feedback.

  • sent: ricevere un messaggio di feedback se il messaggio è stato completato.

  • : ricevere un messaggio di feedback se il messaggio è scaduto (o è stato raggiunto il numero massimo di recapito) senza essere stato completato dal dispositivo.

  • full: feedback per i risultati inviati e non inviati.

In questo esempio, la proprietà ack è impostata su full, richiedendo un feedback sul recapito dei messaggi inviati e non inviati per un messaggio.

message.ack = 'full';

La funzione di richiamata del ricevitore del feedback del messaggio è collegata a Client utilizzando getFeedbackReceiver.

Il destinatario del feedback del messaggio riceve due argomenti:

  • Oggetto Error (può essere null)
  • Oggetto AmqpReceiver: genera eventi quando vengono ricevuti nuovi messaggi di feedback dal client.

Questa funzione di esempio riceve e stampa un messaggio di feedback di recapito nella console.

function receiveFeedback(err, receiver){
  receiver.on('message', function (msg) {
    console.log('Feedback message:')
    console.log(msg.getData().toString('utf-8'));
  });
}

Questo codice collega la funzione di richiamata di feedback receiveFeedback all'oggetto servizio Client tramite getFeedbackReceiver.

serviceClient.getFeedbackReceiver(receiveFeedback);

Definire un gestore dei risultati di completamento dei messaggi

La funzione di richiamata di completamento dell'invio del messaggio viene chiamata dopo l'invio di ciascun messaggio.

Questa funzione di esempio stampa i risultati dell'operazione messaggio send nella console. In questo esempio, la funzione printResultFor viene fornita come parametro alla funzione send descritta nella sezione successiva.

function printResultFor(op) {
  return function printResult(err, res) {
    if (err) console.log(op + ' error: ' + err.toString());
    if (res) console.log(op + ' status: ' + res.constructor.name);
  };
}

Inviare un messaggio

Usare la funzione send per inviare un messaggio asincrono da cloud a dispositivo all'app per dispositivi tramite l'hub IoT.

send supporta questi parametri:

  • deviceID: ID dispositivo del dispositivo di destinazione.
  • message: corpo del messaggio da inviare al dispositivo.
  • done: funzione facoltativa da chiamare al termine dell'operazione. Done viene chiamato con due argomenti:
    • Oggetto Error (può essere null).
    • oggetto risposta specifico del trasporto, utile per la registrazione o il debug.

Questo codice chiama send per inviare un messaggio da cloud a dispositivo all'app per dispositivi tramite l'hub IoT. La funzione di richiamata printResultFor definita nella sezione precedente riceve le informazioni sull'acknowledgement del recapito.

var targetDevice = '{device ID}';
serviceClient.send(targetDevice, message, printResultFor('send'));

Questo esempio mostra come inviare un messaggio al dispositivo e gestire il messaggio di feedback quando il dispositivo riconosce il messaggio da cloud a dispositivo:

serviceClient.open(function (err) {
  if (err) {
    console.error('Could not connect: ' + err.message);
  } else {
    console.log('Service client connected');
    serviceClient.getFeedbackReceiver(receiveFeedback);
    var message = new Message('Cloud to device message.');
    message.ack = 'full';
    message.messageId = "My Message ID";
    console.log('Sending message: ' + message.getData());
    serviceClient.send(targetDevice, message, printResultFor('send'));
  }
});

Esempio di messaggio di invio dell'SDK

send_c2d_message.js: inviare messaggi C2D a un dispositivo tramite l'hub IoT.

Criteri di riconnessione della connessione

Questo articolo non illustra un criterio di ripetizione per il dispositivo alla connessione dell'hub IoT o all'applicazione esterna alla connessione all'hub IoT. Nel codice di produzione, è necessario implementare i criteri di ripetizione di connessione, come descritto in Gestire le riconnessioni dei dispositivi per creare applicazioni resilienti.

Tempo di conservazione dei messaggi, tentativi e numero massimo di consegne

Come descritto in Inviare messaggi da cloud a dispositivo dall'hub IoT, è possibile visualizzare e configurare le impostazioni predefinite per i valori seguenti del messaggio usando le opzioni di configurazione dell'hub IoT del portale o dell'interfaccia della riga di comando di Azure. Queste opzioni di configurazione possono influire sul recapito e sul feedback dei messaggi.

  • TTL predefinita (time to live): tempo durante il quale un messaggio è disponibile per l'uso da parte del dispositivo prima della scadenza nell'hub IoT,.
  • Tempo di conservazione del feedback: il tempo in cui l'hub IoT mantiene il feedback per la scadenza o il recapito dei messaggi da cloud a dispositivo.
  • Numero di tentativi dell'hub IoT di recapitare un messaggio da cloud a dispositivo a un dispositivo.