Enviar mensagens de nuvem para dispositivo a partir de um hub IoT

Para enviar notificações unidirecionais para um aplicativo do dispositivo a partir do back-end de solução, envie mensagens de nuvem para dispositivo a partir do seu hub IoT para seu dispositivo. Para uma discussão sobre outras opções de nuvem para dispositivo com suporte do Hub IoT do Azure, consulte Diretrizes de comunicação de nuvem para dispositivo.

Observação

Os recursos descritos neste artigo estão disponíveis apenas na camada padrão do Hub IoT. Para obter mais informações sobre as camadas básica e padrão/gratuita do Hub IoT, confira Escolher a camada certa do Hub IoT para sua solução.

Você pode enviar mensagens da nuvem para o dispositivo por meio de um ponto de extremidade voltado para o serviço ( /messages/devicebound). Um dispositivo recebe as mensagens através de um ponto de extremidade específico do dispositivo /devices/{deviceId}/messages/devicebound.

Para que cada mensagem da nuvem para o dispositivo seja direcionada a um único dispositivo, seu hub IoT define a propriedade to como /devices/{deviceId}/messages/devicebound.

Cada fila de dispositivo contém, no máximo, 50 mensagens da nuvem para o dispositivo. Ocorrerá um erro ao tentar enviar mais mensagens para o mesmo dispositivo.

O ciclo de vida da mensagem da nuvem para o dispositivo

Para garantir uma entrega de mensagem pelo menos uma vez, seu hub IoT persiste mensagens de nuvem para o dispositivo em filas por dispositivo. Os dispositivos devem reconhecer explicitamente a conclusão de uma mensagem antes que o Hub IoT remova a mensagem da fila. Essa abordagem garante a resiliência contra conectividade e falhas de dispositivo.

O gráfico de estado do ciclo de vida é exibido no diagrama a seguir:

Diagrama mostrando o grafo de estado do ciclo de vida das mensagens da nuvem para o dispositivo.

Quando o serviço do hub IoT envia uma mensagem para um dispositivo, o serviço define o estado da mensagem para Enfileirada. Quando um dispositivo quiser receber uma mensagem, o hub IoT bloqueará a mensagem, definindo o estado como invisível. Esse estado permite que outros threads no dispositivo comecem a receber outras mensagens. Quando um thread de dispositivo conclui o processamento de uma mensagem, ele notifica o hub IoT concluindo a mensagem. O hub IoT, em seguida, define o estado para Concluído.

Um dispositivo também pode:

  • Rejeitar a mensagem, fazendo com que o hub IoT defina-a para o estado Mensagens mortas. Os dispositivos que se conectam por meio do protocolo de transporte de telemetria de enfileiramento de mensagens (Message Queuing Telemetry Transport, MQTT) não podem rejeitar mensagens da nuvem para o dispositivo.

  • Abandonar a mensagem, o que faz com que o hub IoT coloque a mensagem de volta na fila com o estado definido como Enfileirada. Os dispositivos que se conectam através do protocolo MQTT não podem abandonar mensagens de nuvem para dispositivo.

Um thread pode falhar ao processar uma mensagem sem notificar o hub IoT. Nesse caso, as mensagens passam automaticamente do estado Invisível de volta para o estado Enfileirada após um tempo limite de visibilidade (ou de bloqueio). O valor desse tempo limite é de um minuto e não pode ser alterado.

A propriedade max delivery count no hub IoT determina o número de vezes que uma mensagem pode transitar entre os estados Enfileirada e Invisível. Após esse número de transições, o hub IoT define o estado da mensagem para Mensagens mortas. Da mesma forma, o hub IoT define o estado de uma mensagem para Mensagens mortas após o tempo de expiração. Para obter mais informações, consulte Expiração da mensagem (tempo de vida).

O artigo Como enviar mensagens de nuvem para dispositivo com Hub IoT mostra como enviar mensagens de nuvem para dispositivo da nuvem e recebê-las em um dispositivo.

Um dispositivo normalmente completa uma mensagem de nuvem para dispositivo quando a perda da mensagem não afeta a lógica de aplicativo. Um exemplo dessa conclusão pode ser quando o dispositivo persistiu o conteúdo da mensagem localmente ou executou uma operação com êxito. A mensagem também poderia portar informações transitórias cuja perda não afetaria a funcionalidade do aplicativo. Às vezes, para tarefas de execução longa, você pode:

  • Completar a mensagem do dispositivo para a nuvem depois que o dispositivo tiver persistido a descrição da tarefa no armazenamento local.

  • Notificar o back-end da solução com uma ou mais mensagens de dispositivo para a nuvem em vários estágios de progresso da tarefa.

Expiração da mensagem (vida útil)

Todas as mensagens da nuvem para o dispositivo têm um tempo de expiração. Esse tempo é definido por um dos seguintes opções:

  • A propriedade ExpiryTimeUtc no serviço
  • O hub IoT usando a vida útil padrão especificada como uma propriedade de hub IoT

Para obter mais informações sobre a expiração da mensagem, consulte Opções de configuração de nuvem para dispositivo.

Uma maneira comum de tirar proveito da expiração de uma mensagem para evitar enviar mensagens para dispositivos desconectados é definir valores de vida útil baixos. Essa abordagem proporciona o mesmo resultado que a manutenção do estado de conexão do dispositivo, mas é mais eficiente. Quando você solicita confirmações de mensagem, o hub IoT notifica quais dispositivos:

  • São capazes de receber mensagens.
  • Não estão online ou falharam.

Comentários da mensagem

Quando você envia uma mensagem da nuvem para o dispositivo, o serviço pode solicitar a entrega de um comentário por mensagem sobre o estado final dela. Configure a mensagem de comentários definindo a propriedade de aplicativo iothub-ack na mensagem da nuvem para o dispositivo que está sendo enviada para um dos quatro valores a seguir:

Valor da propriedade Ack Comportamento
nenhum Padrão. O hub IoT não gera uma mensagem de comentários.
positivo Se a mensagem da nuvem para o dispositivo alcança o estado Concluído, o hub IoT gera uma mensagem de comentários.
negativo Se a mensagem de nuvem para dispositivo alcançar o estado Mensagens mortas, o hub IoT gerará uma mensagem de comentários.
completa O hub IoT gera uma mensagem de comentários em ambos os casos.

Se o valor da propriedade Ack estiver definida como total e você não receber uma mensagem de comentários, isso significará que a mensagem de comentários expirou. O serviço não pode saber o que aconteceu com a mensagem original. Na prática, um serviço deve garantir que possa processar os comentários antes que eles expirem. O tempo de expiração máximo é de dois dias, tempo suficiente para restabelecer a execução do serviço caso ocorra uma falha.

Como explicado em Pontos de extremidade, o hub IoT fornece comentários por meio de um ponto de extremidade voltado para o serviço /messages/servicebound/feedback, como mensagens. A semântica de recebimento dos comentários é a mesma das mensagens da nuvem para o dispositivo. Sempre que possível, os comentários de mensagem são feitos em lotes em uma única mensagem, com o seguinte formato:

Propriedade Descrição
EnqueuedTime Um carimbo de data/hora que indica quando a mensagem de comentários foi recebida pelo hub.
UserId {iot hub name}
ContentType application/vnd.microsoft.iothub.feedback.json

O sistema enviará os comentários quando o lote chegar a 64 mensagens ou em 15 segundos desde o último envio, o que ocorrer primeiro.

O corpo é uma matriz de registros serializada em JSON, cada um com as seguintes propriedades:

Propriedade Descrição
enqueuedTimeUtc Um carimbo de data/hora que indica quando ocorreu a saída da mensagem. Por exemplo, um carimbo de data/hora que indica quando o Hub recebeu a mensagem de comentários ou a mensagem original expirou.
originalMessageId A MessageId da mensagem de nuvem para dispositivo para qual essa informação de comentários se relaciona.
statusCode Uma cadeia de caracteres necessária, usada em mensagens de comentários que são geradas pelo hub IoT:
Êxito
Expirada
DeliveryCountExceeded
Rejeitado
Limpo
descrição Valores de cadeia de caracteres para StatusCode.
deviceId A DeviceId do dispositivo de destino da mensagem de nuvem para dispositivo para qual esse comentário se relaciona.
deviceGenerationId A DeviceGenerationId do dispositivo de destino da mensagem de nuvem para dispositivo para qual esse comentário se relaciona.

O serviço deve especificar uma MessageIdpara que a mensagem da nuvem para o dispositivo possa correlacionar seus comentários com a mensagem original.

Veja como fica o corpo de uma mensagem de comentários no seguinte exemplo de código:

[
  {
    "originalMessageId": "0987654321",
    "enqueuedTimeUtc": "2015-07-28T16:24:48.789Z",
    "statusCode": "Success",
    "description": "Success",
    "deviceId": "123",
    "deviceGenerationId": "abcdefghijklmnopqrstuvwxyz"
  },
  {
    ...
  },
  ...
]

Comentários pendentes para dispositivos excluídos

Quando um dispositivo é excluído, todos os comentários pendentes também são excluídos. Os comentários do dispositivo são enviados em lotes. Uma janela estreita, geralmente menor que um segundo, pode ocorrer entre quando um dispositivo confirma o recebimento da mensagem e quando o próximo lote de comentários é preparado. Se um dispositivo for excluído nessa janela estreita, os comentários não ocorrerão.

Você pode resolver esse comportamento aguardando um tempo para que os comentários pendentes cheguem, antes de excluir o dispositivo. Comentários de mensagem relacionados devem ser considerados perdidos depois que um dispositivo é excluído.

Opções de configuração da nuvem para o dispositivo

Cada Hub IoT expõe as seguintes opções de configuração para mensagens de nuvem para o dispositivo:

Propriedade Descrição Intervalo e padrão
defaultTtlAsIso8601 TTL padrão para mensagens da nuvem para o dispositivo Intervalo ISO_8601 de até dois dias (mínimo de um minuto); padrão: um hora
maxDeliveryCount Contagem máxima de entrega para filas de nuvem para dispositivo por dispositivo 1 a 100; padrão: 10
feedback.ttlAsIso8601 Retenção de mensagens informativas do serviço associado Intervalo ISO_8601 de até dois dias (mínimo de um minuto); padrão: um hora
feedback.maxDeliveryCount Contagem máxima de entrega para a fila de comentários 1 a 100; padrão: 10
feedback.lockDurationAsIso8601 Duração do bloqueio para a fila de comentários Intervalo ISO_8601 de 5 a 300 segundos (mínimo de cinco segundos); padrão: 60 segundos.

Você pode definir as opções de configuração de uma das seguintes maneiras:

  • Portal do Microsoft Azure: em Configurações de hub no hub IoT, selecione Pontos de extremidade internos e acesse Mensagens de nuvem para dispositivo. (A definição das propriedades feedback. maxDeliveryCount e feedback. lockDurationAsIso8601 não tem suporte no portal do Azure no momento.)

Defina opções de configuração para mensagens da nuvem para dispositivo no portal

  • CLI do Azure: use o comando az iot hub update:

    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.defaultTtlAsIso8601=PT1H0M0S
    
    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.maxDeliveryCount=10
    
    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.feedback.ttlAsIso8601=PT1H0M0S
    
    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.feedback.maxDeliveryCount=10
    
    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.feedback.lockDurationAsIso8601=PT0H1M0S
    

Próximas etapas

Para obter informações sobre os SDKs que você pode utilizar para receber mensagens de nuvem para dispositivo, consulte SDKs do Hub IoT do Azure.

Para experimentar a recepção de mensagens de nuvem para dispositivo, consulte o tutorial Enviar de nuvem para dispositivo .