Inviare messaggi dal cloud al dispositivo con Hub IoT (.NET)

L'hub IoT di Azure è un servizio completamente gestito che consente di abilitare comunicazioni bidirezionali affidabili e sicure tra milioni di dispositivi e un back-end della soluzione. L'argomento di avvio rapido Send telemetry from a device to an IoT hub (Inviare dati di telemetria da un dispositivo a un hub IoT) mostra come creare un hub IoT, eseguire il provisioning dell'identità di un dispositivo al suo interno e creare il codice di un'app per dispositivo che invia messaggi da dispositivo a cloud.

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.

Questa esercitazione è basata su Send telemetry from a device to an IoT hub (Inviare dati di telemetria da un dispositivo a un hub IoT). Illustra come eseguire le attività seguenti:

  • Dal back-end della soluzione inviare messaggi da cloud a dispositivo a un singolo dispositivo tramite l'hub IoT.

  • Ricevere messaggi da cloud a dispositivo in un dispositivo.

  • Dal back-end della soluzione richiedere l'acknowledgement di recapito (feedback) per i messaggi inviati a un dispositivo dall'hub IoT.

Altre informazioni sui messaggi da cloud a dispositivo sono disponibili in Messaggistica da dispositivo a cloud e da cloud a dispositivo con l'hub IoT.

Al termine di questa esercitazione vengono eseguite due app console .NET.

  • SimulatedDevice. Questa app si connette all'hub IoT e riceve i messaggi da cloud a dispositivo. Questa app è una versione modificata dell'app creata in Send telemetry from a device to an IoT hub (Inviare dati di telemetria da un dispositivo a un hub IoT).

  • SendCloudToDevice. Questa app invia un messaggio da cloud a dispositivo all'app per dispositivo tramite l'hub IoT e riceve quindi l'acknowledgment del recapito.

Nota

hub IoT ha supporto SDK per molte piattaforme e linguaggi di dispositivo, tra cui C, Java, Python e JavaScript, tramite Azure IoT SDK del dispositivo. Per istruzioni dettagliate su come connettere il dispositivo al codice dell'esercitazione e in generale all'hub IoT di Azure, vedere la Guida per sviluppatori dell'hub IoT.

Prerequisiti

  • Visual Studio

  • Un account Azure attivo. Se non si ha un account, è possibile creare un account gratuito in pochi minuti.

  • Assicurarsi che la porta 8883 sia aperta nel firewall. L'esempio di dispositivo di questo articolo usa il protocollo MQTT, che comunica tramite la porta 8883. Questa porta potrebbe essere bloccata in alcuni ambienti di rete aziendali e didattici. Per altre informazioni e soluzioni alternative per questo problema, vedere Connettersi all'hub IoT (MQTT).

Ricevere messaggi nell'app per dispositivi

In questa sezione si modifica l'app per dispositivi creata in Send telemetry from a device to an IoT hub (Inviare dati di telemetria da un dispositivo a un hub IoT) per ricevere messaggi da cloud a dispositivo dall'hub IoT.

  1. In Visual Studio, nel progetto SimulatedDevice aggiungere il metodo seguente alla classe SimulatedDevice.

     private static async void ReceiveC2dAsync()
     {
         Console.WriteLine("\nReceiving cloud to device messages from service");
         while (true)
         {
             Message receivedMessage = await s_deviceClient.ReceiveAsync();
             if (receivedMessage == null) continue;
    
             Console.ForegroundColor = ConsoleColor.Yellow;
             Console.WriteLine("Received message: {0}", 
             Encoding.ASCII.GetString(receivedMessage.GetBytes()));
             Console.ResetColor();
    
             await s_deviceClient.CompleteAsync(receivedMessage);
         }
     }
    
  2. Aggiungere il metodo seguente al metodo Main immediatamente prima della riga Console.ReadLine():

    ReceiveC2dAsync();
    

Il metodo ReceiveAsync restituisce in modo asincrono il messaggio ricevuto nel momento in cui viene ricevuto dal dispositivo. Restituisce Null dopo un periodo di timeout specificabile. In questo esempio viene usato il valore predefinito di un minuto. Quando l'app riceve un valore Null, deve rimanere in attesa di nuovi messaggi. Questo requisito è il motivo per la riga if (receivedMessage == null) continue.

La chiamata a notifica hub IoT CompleteAsync() che il messaggio è stato elaborato correttamente e che il messaggio può essere rimosso in modo sicuro dalla coda del dispositivo. Il dispositivo deve chiamare questo metodo quando l'elaborazione viene completata correttamente indipendentemente dal protocollo in uso.

Con AMQP e HTTPS, ma non MQTT, il dispositivo può anche:

  • Abbandonare un messaggio, che comporta hub IoT conservare il messaggio nella coda del dispositivo per l'utilizzo futuro.
  • Rifiutare un messaggio, che rimuove definitivamente il messaggio dalla coda del dispositivo.

Se si verifica qualcosa che impedisce al dispositivo di completare, abbandonare o rifiutare il messaggio, hub IoT verrà eseguito dopo un periodo di timeout fisso, accodare nuovamente il messaggio per il recapito. Per questo motivo, la logica di elaborazione dei messaggi nell'app per dispositivi deve essere idempotente, in modo che la ricezione dello stesso messaggio più volte produa lo stesso risultato.

Per informazioni più dettagliate su come hub IoT elabora i messaggi da cloud a dispositivo, inclusi i dettagli del ciclo di vita dei messaggi da cloud a dispositivo, vedere Inviare messaggi da cloud a dispositivo da un hub IoT.

Nota

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

Ottenere la stringa di connessione dell'hub IoT

In questo articolo viene creato un servizio back-end per l'invio di messaggi da cloud a dispositivo tramite l'hub IoT creato in Send telemetry from a device to an IoT hub (Inviare dati di telemetria da un dispositivo a un hub IoT). Per inviare messaggi da cloud a dispositivo, è necessario che il servizio disponga dell'autorizzazione di connessione al servizio. Per impostazione predefinita, ogni hub IoT viene creato con un servizio con nome di criteri di accesso condiviso che concede tale autorizzazione.

Per ottenere la stringa di connessione dell'hub IoT per i criteri del servizio, seguire questa procedura:

  1. Nel portale di Azure fare clic su Gruppi di risorse. Selezionare il gruppo di risorse in cui si trova l'hub e quindi selezionare l'hub dall'elenco di risorse.

  2. Nel riquadro sinistro dell'hub IoT selezionare Criteri di accesso condiviso.

  3. Dall'elenco dei criteri selezionare i criteri del servizio.

  4. In Chiavi di accesso condiviso selezionare l'icona di copia per la stringa di connessione primaria e salvare il valore.

Screenshot that shows how to retrieve the connection string

Per altre informazioni sui criteri di accesso condiviso e sulle autorizzazioni dell'hub IoT, vedere Controllo dell'accesso e autorizzazioni.

Inviare un messaggio da cloud a dispositivo

In questa sezione viene creata un'app console .NET che invia messaggi da cloud a dispositivo all'app del dispositivo simulato.

  1. Nella soluzione corrente di Visual Studio, selezionare File>Nuovo>Progetto. In Crea un nuovo progetto, selezionare App console (.NET Framework) , quindi selezionare Avanti.

  2. Denominare il progetto SendCloudToDevice. In Soluzione selezionare Aggiungi a soluzione e accettare la versione più recente del .NET Framework. Selezionare Crea per creare il progetto.

    Configure a new project in Visual Studio

  3. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nuovo progetto e quindi scegliere Gestisci pacchetti NuGet.

  4. In Gestisci pacchetti NuGet selezionare Sfoglia e cercare e selezionare Microsoft.Azure.Devices. Selezionare Installa.

    In questo passaggio verrà quindi scaricato e installato il pacchetto NuGet Azure IoT Service SDK e verrà aggiunto un riferimento a tale pacchetto.

  5. Aggiungere l'istruzione using seguente all'inizio del file Program.cs.

    using Microsoft.Azure.Devices;
    
  6. Aggiungere i campi seguenti alla classe Program . Sostituire il {iot hub connection string} valore segnaposto con la stringa di connessione dell'hub IoT annotata in precedenza in Ottenere la stringa di connessione dell'hub IoT. Sostituire il {device id} valore segnaposto con l'ID dispositivo del dispositivo aggiunto nella guida introduttiva Invia dati di telemetria da un dispositivo a un hub IoT .

    static ServiceClient serviceClient;
    static string connectionString = "{iot hub connection string}";
    static string targetDevice = "{device id}";
    
  7. Aggiungere il metodo seguente alla classe Program per inviare un messaggio al dispositivo.

    private async static Task SendCloudToDeviceMessageAsync()
    {
         var commandMessage = new
          Message(Encoding.ASCII.GetBytes("Cloud to device message."));
         await serviceClient.SendAsync(targetDevice, commandMessage);
    }
    
  8. Aggiungere infine le righe seguenti al metodo Main .

    Console.WriteLine("Send Cloud-to-Device message\n");
    serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
    
    Console.WriteLine("Press any key to send a C2D message.");
    Console.ReadLine();
    SendCloudToDeviceMessageAsync().Wait();
    Console.ReadLine();
    
  9. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla soluzione e selezionare Imposta progetti di avvio.

  10. In CommonPropertiesStartup> Project selezionare Più progetti di avvio e quindi selezionare l'azione Start per SimulatedDevice e SendCloudToDevice. Selezionare OK per salvare le modifiche.

  11. Premere F5. Si avviano entrambe le applicazioni. Selezionare la finestra SendCloudToDevice e premere INVIO. Verrà visualizzato il messaggio ricevuto dall'app per dispositivi.

    Device app receiving message

Ricevere feedback di recapito

È possibile richiedere la conferma della ricezione (o della scadenza) dall'hub IoT per ogni messaggio da cloud a dispositivo. Questa opzione consente al back-end della soluzione di informare facilmente la logica di ripetizione o di compensazione. Per altre informazioni sul feedback dei messaggi da cloud a dispositivo, vedere Messaggistica da dispositivo a cloud e da cloud a dispositivo con l'hub IoT.

In questa sezione si modifica l'app SendCloudToDevice per richiedere feedback e riceverlo dall'hub IoT.

  1. In Visual Studio, nel progetto SendCloudToDevice aggiungere il seguente metodo alla classe Programma.

    private async static void ReceiveFeedbackAsync()
    {
         var feedbackReceiver = serviceClient.GetFeedbackReceiver();
    
         Console.WriteLine("\nReceiving c2d feedback from service");
         while (true)
         {
             var feedbackBatch = await feedbackReceiver.ReceiveAsync();
             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 il modello di ricezione è identico a quello usato per ricevere messaggi da cloud a dispositivo dall'app per dispositivo.

  2. Aggiungere la riga seguente nel metodo Main immediatamente dopo serviceClient = ServiceClient.CreateFromConnectionString(connectionString).

    ReceiveFeedbackAsync();
    
  3. Per richiedere feedback del recapito del messaggio da cloud a dispositivo, è necessario specificare una proprietà nel metodo SendCloudToDeviceMessageAsync . Aggiungere la riga seguente, subito dopo la riga var commandMessage = new Message(...);.

    commandMessage.Ack = DeliveryAcknowledgement.Full;
    
  4. Premere F5per eseguire le app. Verranno visualizzate entrambe le applicazioni. Selezionare la finestra SendCloudToDevice e premere INVIO. Verrà visualizzata la ricezione del messaggio da parte dell'app per dispositivi e, dopo alcuni secondi, la ricezione del messaggio di feedback da parte dell'applicazione SendCloudToDevice.

    Device app receiving message and service app receiving feedback

Nota

Per semplicità, in questa esercitazione non si implementa alcun criterio di nuovi tentativi. Nel codice di produzione è consigliabile implementare criteri di ripetizione dei tentativi, ad esempio un backoff esponenziale, come suggerito in Gestione degli errori temporanei.

Passaggi successivi

Questa esercitazione ha illustrato come inviare e ricevere messaggi da cloud a dispositivo.

Per altre informazioni sullo sviluppo delle soluzioni con l'hub IoT, vedere la Guida per sviluppatori dell'hub IoT.