Escolhendo o protocolo apropriado para o aplicativo IoT

12

Temos no trabalho um cenário de IoT em que o dispositivo / coisa restrita envia sua posição GPS em um intervalo regular para um determinado servidor. O dispositivo restrito é uma placa semelhante ao Arduino que é alimentada por bateria e usa um escudo GSM / SIM para conectividade. Esses são nossos objetivos de design:

  • Maximizando a vida útil da bateria
  • Minimizando a transferência de dados

Para fins de teste, usamos HTTP, resultando em mensagens em torno dos 500 bytes, mas é hora de usar um protocolo mais apropriado para a transmissão de dados. Algumas das características da transferência de dados são estas:

  • A carga útil é bem pequena, normalmente com menos de 50 bytes (bem longe das MTUs típicas, ou seja, tudo deve caber em um pacote IP)
  • Os dados devem ser enviados aproximadamente uma vez por minuto . Alguma variação não é crítica.
  • Não há problema em perder algumas mensagens
  • No momento, o dispositivo não precisa de nenhum tipo de resposta do serviço r (no entanto, isso pode mudar no futuro). Nem o servidor precisa iniciar qualquer conversa com os dispositivos.

Até agora, pensamos nessas possibilidades:

  • Protocolo personalizado sobre TCP . Isso eliminaria os cabeçalhos HTTP, tornando a mensagem 10 vezes menor. Essa é a nossa abordagem confiável / conservadora.
  • Protocolo personalizado sobre UDP . Como o UDP possui cabeçalhos menores e sem sobrecarga de confiabilidade, esperamos ser bastante eficientes. Como comentado, perder uma mensagem aqui ou não é uma preocupação ... no entanto, pode haver outros problemas com a não confiabilidade que não conhecemos.
  • MQTT (padrão sobre TCP): Com quase nenhuma sobrecarga existente em comparação com o TCP, isso também poderia ser uma opção ... no entanto, não temos muita experiência com a tecnologia GSM / SIM e não sabemos como uma conexão MQTT contínua funcionaria dessa maneira e se a largura de banda da pulsação da conexão vale a pena para uma transferência de dados de baixa frequência.
  • CoAP (padrão sobre UDP): parece promissor também. Sobrecarga de apenas 4 bytes para os cabeçalhos e trabalho sobre UDP. No entanto, existem riscos desconhecidos de UDP.

Alguém pode dar alguma dica? Desde já, obrigado.

bgusach
fonte
1
@ RichardChambers neste cenário, a confiabilidade não é tão importante. Podemos perder alguns pacotes aqui ou ali. Acknão é necessário. Eu acho que trabalhar com confiabilidade no UDP não faz muito sentido, é para isso que serve o TCP.
bgusach
1
Eu não reinventaria a roda projetando um protocolo personalizado. Um google do CoAP vs. MQTT fornecerá mais considerações. Você precisa preparar sua solução para o futuro, ou seja. lidar com requisitos mais rigorosos no futuro (garantias de perda, tempo de resposta, interoperabilidade etc.)? Os dispositivos são NAT? Existe um agrupamento de dispositivos atrás dos gateways? Many unknowns ...
Gambit Support

Respostas:

6

Algumas reflexões sobre minha experiência com TCP, UDP e MQTT, bem como alguns recursos adicionais a serem revisados.

Com o UDP, deparei-me com o problema de falha silenciosa, no qual um aplicativo em um nó da rede, o cliente, está vendo apenas algumas das mensagens UDP enviadas. Existem muitas razões pelas quais o tráfego de rede pode dar errado. O problema com o UDP é que os pacotes podem ser descartados praticamente sempre que qualquer um dos nós no caminho da rede entre o produtor de pacotes e o consumidor de pacotes justificar. Consulte o tópico Wikipedia Perda de pacotes .

A questão é qual é a sua taxa de perda em qualquer contexto de rede atual. Portanto, se for uma comunicação dentro de uma LAN ou sub-rede, sua taxa de perda poderá ser baixa. Em uma WAN ou na Internet, sua taxa de perda pode ser bastante alta. Os pacotes UDP são descartados por vários motivos e roteados, no entanto, as condições da rede permitem com esse decréscimo na contagem de saltos. O envio de pacotes para o grande vazio sem responsabilidade deixa aberta a possibilidade de falhas silenciosas.

Parece que, no seu caso, apenas uma confirmação simples com retransmissão após um tempo limite sem receber uma confirmação seria suficiente.

Fiz mensagens XML em uma conexão TCP mantida e funcionou muito bem. Eu tinha uma camada que entregava mensagens completas em buffer para a camada de aplicação. Usei XML para empacotar a mensagem com uma marca de início XML para o início da mensagem e uma marca final de XML para saber quando toda a mensagem foi recebida.

O TCP possui alguns recursos, como ordem seqüencial de pacotes, sem repetição e ser um mecanismo de transporte conectado significa que você sabe se a outra extremidade desaparece ou não, embora possa demorar um pouco para descobrir. A conexão e a desconexão podem causar atrasos, mas não onerosas, em condições comuns, embora as condições da rede possam causar a diminuição da taxa de transferência TCP.

MQTT é um protocolo que é transportado por uma camada de transporte de rede, normalmente TCP. O MQTT usa um modelo de publicação / assinatura para que não haja armazenamento de mensagens. Portanto, quando um publicador publica uma mensagem se o assinante não estiver conectado no momento e quando ele se conectar, ele não verá a mensagem. O MQTT é praticamente em tempo real, suponho que é disso que trata a parte de telemetria do acrônimo. Eu gosto do MQTT para pequenas mensagens e tenho feito algumas experiências com a carga útil JSON através do MQTT usando o Mosquitto. Consulte este artigo Entrega confiável de mensagens com o Mosquitto (MQTT) com uma visão geral do MQTT e da qualidade do serviço. E consulte este breve artigo com links para recursos, incluindo um aplicativo de amostra IoT - MQTT Publish e Subscriber C Code .

Minhas experiências com o MQTT usando texto JSON e um banco de dados SQLite3 no assinante para armazenar mensagens estão em https://github.com/RichardChambers/raspberrypi/tree/master/mqtt, embora a fonte esteja em C e seja bastante confusa.

Aqui está um vídeo de 13 minutos # 144 Protocolos da Internet: CoAP vs MQTT, Sniffing de rede e preparação para o IKEA Tradfri Hacking . Este é um artigo interessante sobre CoAP, Protocolo de Aplicação Restrita: CoAP é o protocolo 'moderno' da IoT . Existe este somatório do CoAP:

Os primeiros usuários concordam que o Protocolo de Aplicativo Restrito funciona extremamente bem para redes e dispositivos restritos. Algo pouco conhecido: "Em uma rede sem fio muito congestionada - Wi-Fi ou celular - o CoAP pode continuar a trabalhar onde um protocolo TCP (Transmission Control Protocol) como o MQTT não consegue nem concluir um aperto de mão, "Disse Vermillard.

Isso ocorre porque, diferentemente da maioria dos outros protocolos de IoT, o CoAP é construído sobre o UDP. Em outras palavras, significa que não há handshakes de protocolo ou correção de erros, como encontrado no TCP. "O CoAP pode não ser tão confiável quanto o HTTP ou garantir a entrega de mensagens como o MQTT, mas é extremamente rápido", observou Matthieu. "Se você concorda com algumas mensagens que não estão sendo recebidas, pode enviar muito mais mensagens no mesmo período."

Existem alguns outros, como AMQP, STOMP e CBOR, que você pode ver também. Consulte o site padrão da CBOR , bem como esta tese, Implementação e avaliação do protocolo CBOR . Consulte este artigo, Escolhendo seu protocolo de mensagens: AMQP, MQTT ou STOMP, que compara e contrasta o AMQP, MQTT e STOMP e termina com uma observação sobre o broker RabitMQ:

Felizmente, isso pode ajudar muitos a começar a navegar na sopa de protocolo existente para cada um dos seus casos de uso. Como é comum as empresas terem muitos aplicativos com necessidades diferentes, certamente é possível que você precise dos três intermediários em aplicativos diferentes. É aí que entra um corretor poliglota sólido e multiprotocolo como o RabbitMQ - já que ele pode enviar STOMP, MQTT ou AMQP e liberar um dos outros. Você não precisa ficar preso a um desses protocolos - todos os três são suportados pelo broker RabbitMQ, tornando-o a escolha ideal para interoperabilidade entre aplicativos. A arquitetura do plugin também permite que o RabbitMQ evolua para suportar versões adicionais ou atualizadas desses protocolos no futuro.

Este pacote de compartilhamento de slides de cerca de 60 slides faz uma comparação e contraste entre quatro protocolos diferentes de IoT, atendendo às necessidades de dois grupos diferentes de IoT, Consumidores e Industriais, que têm necessidades diferentes de confiabilidade e robustez. Qual é o padrão de mensagens correto para a IoT? .

Richard Chambers
fonte
4

Soa como um aplicativo perfeito para UDP: topologia cliente-servidor (publicação / subnão é necessária), tolerante à perda de pacotes e grandes lacunas entre transmissões de pacotes únicos, o que significa que a chegada fora de ordem não é um problema.

As economias no estabelecimento de conexão e na sobrecarga de pacotes funcionarão bem a seu favor.

Você só precisa mitigar o problema da falha silenciosa. Muitas maneiras de fazer isso, mas minha sugestão seria que o servidor respondesse toda vez que receber x (por exemplo, 10) pacotes. Dessa forma, o cliente sabe quantos de seus pacotes estão passando e, se estiver abaixo de um limite, pode aumentar a frequência das transmissões para combater a perda de pacotes. Se nada estiver conseguindo, o TCP não ajudará, então é melhor colocar o cliente no modo de emergência até que a condição seja resolvida.

A perda de pacotes UDP pela Internet geralmente não é alta e, se for, geralmente é um fenômeno transitório. O GSM fornece alguma avaliação do buffer e do sinal de rádio e, portanto, fornece alguma tolerância a ruídos espúrios.

Heath Raftery
fonte
4

Você tem restrições externas para usar o GSM / SIM?

Uma alternativa pode ser usar uma rede LoRa que:

  • são altamente otimizados para pequenas cargas úteis
  • foram projetados para uso mínimo de energia (e, portanto, vida útil máxima da bateria)
  • são de longo alcance por design
  • ter classes de conexão (sempre ativadas, reconhecidas, não reconhecidas)
  • tem janelas de download agendadas (por exemplo, para atualizações de firmware ou RX ACKs)

Você pode conectar-se à infraestrutura LoRa comercial ou comunitária existente na maioria dos países, ou pode implantar seus próprios hubs LoRa, se isso for mais apropriado.

Existe desenvolvimento ativo globalmente e fácil disponibilidade de escudos de prototipagem (por exemplo, para o Arduino).

BrendanMcL
fonte
1
Uma vez por minuto, como mencionado na pergunta, é muito frequente para ajustar os intervalos de transmissão de nó LoRa recomendados.
22418 Chris Stratton
1
Concordo 1 minuto é muito frequente. Embora o @bgusach não mencione o aplicativo. Se a carga útil puder ser codificada em binário para reduzir o tamanho e se um intervalo de 3-5 minutos (ou até 10 minutos) for utilizável, pode ser o ideal. De qualquer forma, apenas uma sugestão, pois observo que não foi mencionada anteriormente nas respostas.
BrendanMcL
1
Sim, se eu estiver lendo direito, algo como 50 bytes em intervalos de quatro minutos pode não ser adequado; mas isso precisa ser verificado, pode ser desativado facilmente por pelo menos um fator de dois.
Chris Stratton
1
Interessante, mas temos restrições de GSM / SIM (o objetivo é ser um bem de consumo, algo que possa ser comprado e usado em qualquer lugar sem nenhuma infraestrutura, exceto a rede telefônica).
precisa saber é
3

Eu preferiria uma resposta HTTP mínima com dados JSON ... uma resposta HTTP pode estar muito abaixo da transferência HTTP de 500 bytes e você permanece compatível com muitos clientes para aplicativos Web RESTful.

Uma mensagem HTTP mínima (por exemplo, com resultado JSON) com aproximadamente 130 bytes de dados HTTP é semelhante a:

HTTP/1.1 200 OK
Server: ProprietaryAndroid
Connection: close
Content-Type: application/json
{
  "lat": "42.00000",
  "long": "10.00000"
}

se você quiser apenas enviar dados do seu aplicativo para o servidor, basta usar um HTTP GET no qual define os parâmetros de lat / long como URL. A solicitação possui ainda menos dados que a resposta.

GET /?lat=42.00000&long=10.0000 HTTP/1.1
Host: 192.168.0.2 
User-Agent: Proprietary
Accept: */* 
Connection: close
Christoph Bimminger
fonte
7
Obrigado pela sua resposta, mas não entendo seu ponto de vista com a resposta HTTP. Queremos nos livrar de todo o protocolo HTTP para salvar a transferência de dados. E em cima disso, usando GETpara modificar recursos é a Wrong Thing™de fazer
bgusach
Concordo com você do lado arquitetônico de que outros verbos como POST (como verbo universal) são entretanto mais comuns nas APIs REST. Depende de qual nível de maturidade você está desenvolvendo sua API REST. Só queria mostrar como um HTTP pode ser minimizado, mantendo o benefício da implementação e compatibilidade fáceis com as estruturas existentes (cliente e servidor) e, ao mesmo tempo, manter a legibilidade humana. Responder com uma amostra de resposta foi confuso ... Se você deseja enviar os dados, é claro que usaria uma mensagem POST ou GET - no caso de um POST, com o conteúdo json que mostrei na minha primeira amostra.
Christoph Bimminger
3

Não existe um protocolo "melhor". Apenas muitas vantagens e desvantagens a considerar:

  • Seus dispositivos estarão em redes aleatórias com portas aleatórias bloqueadas? Nesse caso, talvez seja melhor usar HTTPS.

  • Se você enviar UDP, sempre poderá enviar as últimas N medidas sempre, para que a perda de pacotes pequenos seja ignorada. Você também pode enviar pacotes ACK, transformando o UDP em um protocolo confiável. (A maioria dos protocolos sobre o UDP faz isso.)

  • Seus clientes se importarão se seus dados forem expostos sem criptografia? Seus clientes se importarão se os hackers puderem injetar dados ruins nessas conexões não criptografadas? (Se sim, você pode querer criptografia.)

  • O que acontece se alguém fareja seu protocolo e manipula os dados? Você pode impedir que um dispositivo substitua dados por outro?

  • Quantos dispositivos você terá no máximo? Como você vai lidar com todos esses dispositivos? Como você encaminhará os dados para onde eles precisam ir? Como você lida com a manutenção e as atualizações da infraestrutura do servidor? Se você não tem experiência, provavelmente está superestimando sua capacidade de lidar com muitas conexões simultâneas. Talvez seja melhor terceirizar para um fornecedor (e usar seus protocolos, como o AWS IoT).

BraveNewCurrency
fonte
3

Temos um teste exato comparando a taxa de transmissão HTTP x MQTT, veja test2 . No cenário atual, o MQTT trará 50 vezes menos tráfego (e bateria) que o HTTP.

Basicamente, não há diferença entre o MQTT e o TCP simples (no tamanho da mensagem). Eu diria mesmo que basicamente não há diferença entre TCP simples e mensagem binária e JSON na carga útil do MQTT. Dessa forma, é muito mais conveniente usar o MQTT + JSON e contar com esses técnicos para entrega e representação de dados. Apenas nomeie suas chaves mais ou menos curtas.

Em relação ao UDP, se a transmissão for uma vez por minuto, é melhor usar o TCP. Se a transmissão for uma vez a cada 10 a 20 minutos ou mais, você poderá considerar o UDP como uma solução mais eficiente para tráfego / bateria. Se você tentar desenvolver um protocolo próprio com ACKs, recomendo que você use MQTT ou TCP e apenas se concentre no seu caso de negócios.

Em geral - quanto mais simples você o implementar, melhores resultados poderão ser alcançados no menor tempo possível. Se eu fosse você, nesse caso, seria melhor testar o formato binário UDP + próprio e o MQTT + JSON e selecionar um deles. Ou até mesmo iniciei no MQTT + JSON e depois pense se está bom para o meu caso.

shal
fonte
1
Mencionarei aqui algumas palavras contra o UDP. Mantemos um grande sistema de gerenciamento de frota GPS SaaS (mais de 1 milhão de veículos conectados) com clientes em mais de 100 países em todo o mundo. Recentemente, descobrimos que os provedores de Internet dos EUA estão bloqueando os pacotes UDP que saem dos EUA por algum motivo, mesmo para aplicativos M2M. Tudo começou há alguns meses, mas é muito doloroso, por isso recomendo que você selecione o protocolo baseado em TCP (MQTT) e confie nos padrões globais. Algum dia e em alguns países, você será forçado a usar o MQTT nos soquetes da web para manter a conexão. Apenas um pequeno conselho.
21318 shal