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.
Ack
não é necessário. Eu acho que trabalhar com confiabilidade no UDP não faz muito sentido, é para isso que serve o TCP.Respostas:
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:
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:
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? .
fonte
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.
fonte
Você tem restrições externas para usar o GSM / SIM?
Uma alternativa pode ser usar uma rede LoRa que:
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).
fonte
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:
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.
fonte
GET
para modificar recursos é aWrong Thing™
de fazerNã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).
fonte
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.
fonte