Envío de mensajes de nube a dispositivo con IoT Hub (.NET)

IoT Hub de Azure es un servicio totalmente administrado que permite la comunicación bidireccional confiable y segura entre millones de dispositivos y una solución de back-end.

En este artículo aprenderá a:

  • Envío de mensajes de nube a dispositivo (C2D) desde el back-end de la solución a un único dispositivo a través de IoT Hub

  • Reciba mensajes de nube a dispositivo en un dispositivo.

  • Solicitar acuse de recibo (comentarios), desde el backend de su solución, para los mensajes enviados a un dispositivo desde IoT Hub

Nota

Las características descritas en este artículo solo están disponibles en el nivel estándar de IoT Hub. Para obtener más información sobre los niveles Básico y Estándar o Gratis de IoT Hub, consulte Elección del nivel adecuado de IoT Hub para la solución.

Al final de este artículo, ejecutará dos aplicaciones de consola de .NET.

  • MessageReceiveSample: una aplicación de dispositivo de ejemplo incluida con el SDK de IoT de Microsoft Azure para .NET, que se conecta al centro de IoT y recibe mensajes de la nube al dispositivo.

  • SendCloudToDevice: una aplicación de servicio que envía un mensaje de nube a dispositivo a la aplicación de dispositivo mediante IoT Hub y, luego, recibe su confirmación de entrega.

Nota

IoT Hub ofrece compatibilidad con SDK en muchas plataformas de dispositivos y lenguajes (entre los que se incluyen C, Java, Python y JavaScript), mediante los SDK de dispositivo IoT de Azure.

Encontrará más información sobre los mensajes de nube a dispositivo en Mensajería de dispositivo a nube y de nube a dispositivo con IoT Hub.

Requisitos previos

  • Suscripción a Azure. Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.

  • Una instancia de IoT Hub en la suscripción de Azure. Si aún no tiene un centro, puede seguir los pasos descritos en Creación de un centro de IoT.

  • Un dispositivo registrado en su centro de IoT. Si aún no ha registrado un dispositivo, regístrelo en Azure Portal.

  • En este artículo, se usa un código de ejemplo del SDK de Azure IoT para C#.

    • Descargue o clone el repositorio del SDK desde GitHub en la máquina de desarrollo.
    • Asegúrese de que .NET Core 3.0.0 o posterior está instalado en la máquina de desarrollo. Para comprobar la versión, ejecute dotnet --version y descargue .NET si es necesario.
  • Asegúrese de que el puerto 8883 está abierto en el firewall. En el ejemplo de dispositivo de este artículo se usa el protocolo MQTT, que se comunica mediante el puerto 8883. Este puerto puede estar bloqueado en algunos entornos de red corporativos y educativos. Para más información y para saber cómo solucionar este problema, consulte el artículo sobre la conexión a IoT Hub (MQTT).

  • Visual Studio.

Obtener la cadena de conexión del dispositivo

En este artículo, ejecutará una aplicación de ejemplo que simula un dispositivo, que recibe mensajes de la nube al dispositivo enviados a través de IoT Hub. La aplicación de ejemplo MessageReceiveSample incluida con el SDK de IoT de Microsoft Azure para .NET se conecta al centro de IoT y actúa como su dispositivo simulado. En el ejemplo, se usa la cadena de conexión principal del dispositivo registrado en el centro de IoT.

Para obtener la cadena de conexión principal de un dispositivo registrado en el centro de IoT, siga estos pasos:

  1. En Azure Portal, seleccione Grupos de recursos. Seleccione el grupo de recursos donde se encuentra el centro y, a continuación, seleccione el centro en la lista de recursos.

  2. En el panel izquierdo del centro de IoT, en Administración de dispositivos, seleccione Dispositivos.

  3. En la lista de dispositivos, seleccione el dispositivo adecuado.

  4. Copie la Cadena de conexión principal y guarde el valor.

    Captura de pantalla que muestra cómo recuperar la cadena de conexión principal de un dispositivo registrado en su centro de IoT en Azure Portal.

Recepción de mensajes en la aplicación de dispositivo

En esta sección, ejecute la aplicación de dispositivo de ejemplo MessageReceiveSample para recibir mensajes de C2D enviados a través del centro de IoT. Abra un nuevo símbolo del sistema y navegue a la carpeta azure-azure-iot-sdk-csharp\iothub\device\samples\getting started\MessageReceiveSample en la carpeta donde ha expandido el SDK de C# para Azure IoT. Ejecute los siguientes comandos y reemplace el valor del marcador de posición {Your device connection string} por la cadena de conexión del dispositivo que copió del dispositivo registrado en el centro de IoT.

dotnet restore
dotnet run --c "{Your device connection string}"

La siguiente salida procede de la aplicación de dispositivo de ejemplo después de que se inicie correctamente y se conecte al centro de IoT:

5/22/2023 11:13:18 AM> Press Control+C at any time to quit the sample.
     
5/22/2023 11:13:18 AM> Device waiting for C2D messages from the hub...
5/22/2023 11:13:18 AM> Use the Azure Portal IoT hub blade or Azure IoT Explorer to send a message to this device.
5/22/2023 11:13:18 AM> Trying to receive C2D messages by polling using the ReceiveAsync() method. Press 'n' to move to the next phase.

La aplicación de dispositivo de ejemplo sondea los mensajes mediante los métodos ReceiveAsync y CompleteAsync. El método ReceiveC2dMessagesPollingAndCompleteAsync usa el método ReceiveAsync, que devuelve de forma asincrónica el mensaje recibido en el momento en que el dispositivo recibe el mensaje. ReceiveAsync devuelve un valor nulo después de un período de tiempo de espera especificable. En este ejemplo, se usa el valor predeterminado de un minuto. Cuando el dispositivo recibe un valor nulo, debe continuar esperando nuevos mensajes. Este requisito es la razón por la que la aplicación de ejemplo incluye el siguiente bloque de código en el método ReceiveC2dMessagesPollingAndCompleteAsync:

   if (receivedMessage == null)
   {
      continue;
   }

La llamada al método CompleteAsync notifica a IoT Hub que el mensaje se ha procesado correctamente y que se puede quitar de la cola del dispositivo de forma segura. El dispositivo debe llamar a este método cuando el procesamiento se complete correctamente, independientemente del protocolo que utilice.

Con los protocolos AMQP y HTTPS, pero no con el protocolo MQTT, el dispositivo también puede:

  • Abandonar un mensaje, lo que da lugar a que IoT Hub retenga el mensaje en la cola del dispositivo para su posterior consumo.
  • Rechace un mensaje, de forma que este se quite permanentemente de la cola del dispositivo.

Si se produce algo que impide que el dispositivo complete, abandone o rechace el mensaje, IoT Hub, después de un período de tiempo de espera fijo, lo pone en cola para repetir la entrega. Por este motivo, la lógica de procesamiento de mensajes de la aplicación del dispositivo debe ser idempotente, de modo que, si se recibe el mismo mensaje varias veces, se genere el mismo resultado.

Para más información sobre el ciclo de vida de los mensajes de la nube al dispositivo y sobre cómo IoT Hub procesa los mensajes de nube a dispositivo, consulte Enviar mensajes de nube a dispositivo desde un IoT Hub.

Nota

Cuando se usa HTTP en lugar de MQTT o AMQP como transporte, el método ReceiveAsync se devuelve inmediatamente. El patrón admitido para los mensajes de la nube al dispositivo con HTTPS es dispositivos conectados de forma intermitente que buscan mensajes con poca frecuencia (cada 25 minutos como mínimo). Emitir más recepciones HTTP tendrá como resultado la limitación de solicitudes de IoT Hub. Para más información sobre las diferencias entre la compatibilidad con MQTT, AMQP y HTTPS, consulte Guía de comunicación de nube a dispositivo y Elección de un protocolo de comunicación.

Obtención de la cadena de conexión de IoT Hub

En este artículo, creará un servicio back-end para enviar mensajes de la nube al dispositivo a través de la IoT Hub. Para enviar mensajes de nube a un dispositivo, el servicio necesita el permiso de conexión de servicio. De forma predeterminada, todas las instancias de IoT Hub se crean con una directiva de acceso compartido denominada servicio que concede este permiso.

Para obtener la cadena de conexión de IoT Hub para la directiva service, siga estos pasos:

  1. En Azure Portal, seleccione Grupos de recursos. Seleccione el grupo de recursos donde se encuentra el centro y, a continuación, seleccione el centro en la lista de recursos.

  2. En el panel de la izquierda de IoT Hub, seleccione Directivas de acceso compartido.

  3. En la lista de directivas, seleccione la directiva service.

  4. Copie la Cadena de conexión principal y guarde el valor.

Captura de pantalla que muestra cómo recuperar la cadena de conexión de su IoT Hub en el Azure Portal.

Para obtener más información sobre las directivas de acceso compartido y los permisos de IoT Hub, consulte Permisos y control del acceso.

Envío de mensajes de nube a dispositivo

En esta sección, escribirá una aplicación de consola de .NET que envíe mensajes de nube a dispositivo a la aplicación del dispositivo simulado. Necesita el identificador de dispositivo del dispositivo y la cadena de conexión de IoT Hub.

  1. Abra Visual Studio, seleccione Archivo>Nuevo>Proyecto. En Crear un proyecto, seleccione Aplicación de consola (.NET Framework) y seleccione Siguiente.

  2. Asigne al proyecto el nombre SendCloudToDevice y, a continuación, seleccione Siguiente.

    Captura de pantalla de la ventana emergente

  3. Acepte la versión más reciente del marco .NET. Seleccione Crear para crear el proyecto.

  4. En el Explorador de soluciones, haga clic con el botón derecho en el nuevo proyecto y, después, seleccione Administrar paquetes NuGet.

  5. En Administrar paquetes NuGet, seleccione Examinar y busque y seleccione Microsoft.Azure.Devices. Seleccione Instalar.

    En ese paso, se descarga, instala y agrega una referencia al paquete NuGet del SDK de Servicios IoT de Azure.

  6. Agregue la instrucción using en la parte superior del archivo Program.cs.

    using Microsoft.Azure.Devices;
    
  7. Agregue los campos siguientes a la clase Program . Reemplace el valor del marcador de posición {iot hub connection string} por la cadena de conexión del centro de IoT que tomó anteriormente de Obtención de la cadena de conexión del centro de IoT. Reemplace el valor del marcador de posición {device id} por el id. de dispositivo del dispositivo registrado en el centro de IoT.

    static ServiceClient serviceClient;
    static string connectionString = "{iot hub connection string}";
    static string targetDevice = "{device id}";
    
  8. Agregue el método siguiente a la clase de Programa para enviar un mensaje al dispositivo.

    private async static Task SendCloudToDeviceMessageAsync()
    {
         var commandMessage = new
          Message(Encoding.ASCII.GetBytes("Cloud to device message."));
         await serviceClient.SendAsync(targetDevice, commandMessage);
    }
    
  9. Finalmente, agregue las líneas siguientes al método 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();
    
  10. Presione F5 para iniciar la aplicación de servicio de ejemplo. Seleccione la ventana SendCloudToDevice y presione Entrar. Debería ver el mensaje recibido por la aplicación de dispositivo de ejemplo, como se muestra en el ejemplo de salida siguiente.

    5/22/2023 11:13:18 AM> Press Control+C at any time to quit the sample.
    
    5/22/2023 11:13:18 AM> Device waiting for C2D messages from the hub...
    5/22/2023 11:13:18 AM> Use the Azure Portal IoT hub blade or Azure IoT Explorer to send a message to this device.
    5/22/2023 11:13:18 AM> Trying to receive C2D messages by polling using the ReceiveAsync() method. Press 'n' to move to the next phase.
    5/22/2023 11:15:18 AM> Polling using ReceiveAsync() - received message with Id=
    5/22/2023 11:15:18 AM> Received message: [Cloud to device message.]
            Content type:
    
    5/22/2023 11:15:18 AM> Completed C2D message with Id=.
    

Recepción de comentarios de entrega

Es posible solicitar confirmaciones de entrega (o expiración) del Centro de IoT para cada mensaje de nube a dispositivo. Esta opción permite que el back-end de solución notifique fácilmente la lógica de reintento o compensación. Para más información sobre los comentarios de nube a dispositivo, consulte Mensajería de dispositivo a nube y de nube a dispositivo con IoT Hub.

En esta sección, modificará la aplicación de servicio de ejemplo SendCloudToDevice para solicitar comentarios y recibirlos de IoT Hub.

  1. En Visual Studio, en el proyecto SendCloudToDevice, agregue el método siguiente a la clase Program.

    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);
         }
     }
    

    Tenga en cuenta que este patrón de recepción es el mismo que se usa para recibir mensajes de nube a dispositivo desde la aplicación de dispositivo.

  2. Agregue la línea siguiente en el método Main inmediatamente después de serviceClient = ServiceClient.CreateFromConnectionString(connectionString).

    ReceiveFeedbackAsync();
    
  3. Para solicitar comentarios de la entrega del mensaje de la nube a un dispositivo, debe especificar una propiedad en el método SendCloudToDeviceMessageAsync . Agregue la línea siguiente, inmediatamente después de la línea var commandMessage = new Message(...);.

    commandMessage.Ack = DeliveryAcknowledgement.Full;
    
  4. Asegúrese de que la aplicación de dispositivo de ejemplo se está ejecutando y, luego, ejecute la aplicación de servicio de ejemplo al presionar F5. Seleccione la ventana de la consola SendCloudToDevice y presione Entrar. Verá los mensajes que recibe la aplicación de dispositivo de muestra y, al cabo de unos segundos, el mensaje de comentarios que recibe la aplicación SendCloudToDevice. En la salida siguiente, se muestra el mensaje de comentarios recibido por la aplicación de servicio de ejemplo:

    Send Cloud-to-Device message
    
    
    Receiving c2d feedback from service
    Press any key to send a C2D message.
    
    Received feedback: Success
    

Nota

Para hacerlo más simple, este artículo no implementa ninguna directiva de reintentos. En el código de producción, deberá implementar directivas de reintentos (por ejemplo, retroceso exponencial), tal y como se sugiere en el artículo Control de errores transitorios.

Pasos siguientes

En este artículo, ha aprendido a enviar y recibir mensajes de la nube al dispositivo.