Elegir el protocolo apropiado para la aplicación IoT


12

Tenemos en funcionamiento un escenario de IoT donde el dispositivo Thing / Constrained envía su posición GPS en un intervalo regular a un servidor determinado. El dispositivo restringido es una placa tipo Arduino que funciona con baterías y utiliza un escudo GSM / SIM para la conectividad. Esos son nuestros objetivos de diseño:

  • Maximizando la vida de la batería
  • Minimizando la transferencia de datos

Para fines de prueba, hemos utilizado HTTP que da como resultado mensajes de alrededor de los 500 bytes, pero es hora de usar un protocolo más apropiado para la transmisión de datos. Algunas de las características de la transferencia de datos son estas:

  • La carga útil es bastante pequeña, normalmente menos de 50 bytes (bastante lejos de las MTU típicas, es decir, todo debería caber en un paquete IP)
  • Los datos deben enviarse aproximadamente una vez por minuto . Alguna variación no es crítica.
  • Está bien perder algunos mensajes
  • En este momento, el dispositivo no necesita ningún tipo de respuesta del servidor (sin embargo, esto podría cambiar en el futuro). Tampoco el servidor tiene que iniciar ninguna conversación con los dispositivos.

Hasta ahora hemos pensado en estas posibilidades:

  • Protocolo personalizado sobre TCP . Esto eliminaría los encabezados HTTP haciendo que el mensaje sea 10 veces más pequeño. Este es nuestro enfoque confiable / conservador.
  • Protocolo personalizado sobre UDP . Dado que UDP tiene encabezados más pequeños y ninguna sobrecarga para la confiabilidad, esperamos ser bastante eficientes. Como se comentó, perder un mensaje aquí o allá no es una preocupación ... sin embargo, puede haber otros problemas con la falta de confiabilidad que desconocemos.
  • MQTT (estándar sobre TCP): con casi ninguna sobrecarga existente en comparación con TCP, esto también podría ser una opción ... sin embargo, no tenemos mucha experiencia con la tecnología GSM / SIM y no sabemos cómo una conexión MQTT continua funcionaría de esta manera, y si el ancho de banda de latido de la conexión vale para una transferencia de datos de tan baja frecuencia.
  • CoAP (estándar sobre UDP): Parece prometedor también. Solo 4 bytes de sobrecarga para los encabezados y trabajando sobre UDP. Sin embargo, existen riesgos desconocidos de UDP.

¿Alguien puede dar alguna pista? Gracias por adelantado.


1
@RichardChambers en este escenario, la fiabilidad no es tan importante. Podemos permitirnos perder algunos paquetes aquí o allá. Acking no es necesario. Creo que trabajar en confiabilidad además de UDP no tiene demasiado sentido, para eso es TCP.
bgusach

1
No reinventaría la rueda diseñando un protocolo personalizado. Un google de CoAP vs. MQTT le dará más consideraciones. ¿Necesita preparar su solución para el futuro? manejar requisitos más estrictos en el futuro (garantías de pérdida, tiempo de respuesta, interoperabilidad, etc.) ¿Son los dispositivos NAT'ed? ¿Hay agrupación de dispositivos detrás de las puertas de enlace? Muchas incógnitas ...
Gambit Support

Respuestas:


6

Algunas reflexiones sobre mi experiencia con TCP, UDP y MQTT, así como algunos recursos adicionales para revisar.

Con UDP, me he encontrado con el problema de falla silenciosa en el que una aplicación en un nodo de red, el cliente, solo ve algunos de los mensajes UDP que se enviaron. Hay demasiadas razones por las cuales el tráfico de red puede salir mal. El problema con UDP es que los paquetes se pueden descartar casi siempre que cualquiera de los nodos en la ruta de red entre el productor de paquetes y el consumidor de paquetes justifica. Consulte el tema de Wikipedia Pérdida de paquetes .

La pregunta es cuál es su tasa de pérdida en cualquier contexto de red actual. Entonces, si esto es comunicación dentro de una LAN o subred, su tasa de pérdida puede ser baja. En una WAN o en Internet, su tasa de pérdida puede ser bastante alta. Los paquetes UDP se descartan por varias razones y se enrutan, sin embargo, las condiciones de red lo permiten con la disminución del conteo de saltos. El envío de paquetes al gran vacío sin responsabilidad deja abierta la posibilidad de fallas silenciosas.

Parece que en su caso, un simple reconocimiento con retransmisión después de un tiempo de espera sin recibir un reconocimiento sería suficiente.

He hecho mensajes XML a través de una conexión TCP mantenida y funcionó muy bien. Tenía una capa que entregaba mensajes completos cada uno en un búfer a la capa de aplicación para manejar. Utilicé XML para empaquetar el mensaje con una etiqueta de inicio XML para el comienzo del mensaje y una etiqueta de finalización XML para saber cuándo se había recibido todo el mensaje.

TCP tiene algunas características, como el orden secuencial de los paquetes, no se repite, y ser un mecanismo de transporte conectado significa que usted sabe si el otro extremo desaparece o no, aunque puede llevar un tiempo descubrirlo. Conectarse y desconectarse puede generar demoras, pero no resulta oneroso en condiciones normales, aunque las condiciones de la red pueden hacer que el rendimiento del TCP disminuya.

MQTT es un protocolo que es transportado por una capa de transporte de red, normalmente TCP. MQTT utiliza un modelo de publicación / suscripción para que no haya almacenamiento de mensajes. Entonces, cuando un editor publica un mensaje si el suscriptor no está conectado en ese momento, cuando se conecta, no verá el mensaje. MQTT es más o menos en tiempo real, supongo que de eso se trata la parte de las siglas de telemetría. Me gusta MQTT para mensajes pequeños y he estado haciendo algunos experimentos con la carga JSON a través de MQTT usando Mosquitto. Consulte este artículo Entrega confiable de mensajes con Mosquitto (MQTT) con una descripción general de MQTT y la calidad del servicio. Y vea este breve artículo con enlaces a recursos que incluyen una aplicación de ejemplo IoT - MQTT Publish and Subscriber C Code .

Mis experimentos con MQTT usando texto JSON y una base de datos SQLite3 en el suscriptor para almacenar mensajes están en https://github.com/RichardChambers/raspberrypi/tree/master/mqtt aunque la fuente está en C y es bastante desordenada.

Aquí hay un video de 13 minutos # 144 Protocolos de Internet: CoAP vs MQTT, Network Sniffing y preparación para el pirateo de IKEA Tradfri . Este es un artículo interesante sobre CoAP, Protocolo de aplicación restringida: CoAP es el protocolo 'moderno' de IoT . Existe esta suma de CoAP:

Los primeros usuarios están de acuerdo en que el Protocolo de aplicación restringida funciona extremadamente bien para redes y dispositivos restringidos. Algo no tan conocido: "En una red inalámbrica muy congestionada (Wi-Fi o celular), CoAP puede continuar funcionando donde un protocolo basado en el Protocolo de control de transmisión (TCP) como MQTT ni siquiera puede lograr completar un apretón de manos, "Dijo Vermillard.

Esto se debe a que, a diferencia de la mayoría de los otros protocolos de IoT, CoAP se basa en UDP. En otras palabras, significa que no hay protocolos de protocolo de enlace o corrección de errores como se encuentra con TCP. "CoAP puede no ser tan confiable como HTTP o garantizar la entrega de mensajes como MQTT, pero es extremadamente rápido", señaló Matthieu. "Si está de acuerdo con que algunos mensajes no se reciban, puede enviar muchos más mensajes dentro del mismo período de tiempo".

Hay algunos otros, como AMQP, STOMP y CBOR, que también podría considerar. Consulte el sitio web estándar de CBOR , así como esta tesis, implementación y evaluación del protocolo CBOR . Consulte este artículo, Cómo elegir su protocolo de mensajería: AMQP, MQTT o STOMP, que compara y contrasta el AMQP, MQTT y STOMP y termina con una nota sobre el corredor RabitMQ:

Con suerte, esto puede ayudar a muchos a comenzar a navegar la sopa de protocolos para cada uno de sus casos de uso. Dado que es común que las empresas tengan muchas aplicaciones con diferentes necesidades, es posible que necesite los tres corredores en diferentes aplicaciones. Ahí es donde entra en juego un agente políglota sólido y multiprotocolo como RabbitMQ, ya que puede enviar STOMP, MQTT o AMQP y obtener uno de los otros. No necesita estar encerrado por uno de estos protocolos: los tres son compatibles con el intermediario RabbitMQ, lo que lo convierte en una opción ideal para la interoperabilidad entre aplicaciones. La arquitectura del complemento también permite que RabbitMQ evolucione para admitir versiones adicionales o actualizadas de estos protocolos en el futuro.

Este paquete de compartir diapositivas de unas 60 diapositivas compara y contrasta entre cuatro protocolos de IoT diferentes que analizan las necesidades de dos grupos de IoT diferentes, Consumers e Industrial, que tienen diferentes necesidades de confiabilidad y robustez. ¿Cuál es el estándar de mensajería correcto para el IoT? .


4

Suena como una aplicación perfecta para UDP: la topología cliente-servidor (no se requiere pub / sub), tolerante a la pérdida de paquetes y las grandes brechas entre las transmisiones de paquetes individuales significa que la llegada fuera de servicio no es un problema.

Los ahorros en el establecimiento de conexiones y la sobrecarga de paquetes funcionarán bien a su favor.

Solo necesita mitigar el problema del fallo silencioso. Hay muchas maneras de hacer esto, pero mi sugerencia sería que el servidor responda cada vez que reciba x (por ejemplo, 10) paquetes. De esta forma, el cliente sabe cuántos paquetes está recibiendo y, si está por debajo de un umbral, puede aumentar la frecuencia de las transmisiones para contrarrestar la pérdida de paquetes. Si no pasa nada, entonces TCP no va a ayudar de todos modos, por lo que es mejor que solo ponga al cliente en modo de emergencia hasta que la condición desaparezca.

La pérdida de paquetes UDP a través de Internet generalmente no es alta, y si lo es, generalmente es un fenómeno transitorio. GSM proporciona cierta evaluación de la señal de radio y almacenamiento en búfer, por lo que proporciona cierta tolerancia al ruido espurio de todos modos.


4

¿Tiene limitaciones externas para usar GSM / SIM?

Una alternativa puede ser usar una red LoRa que:

  • están altamente optimizados para pequeñas cargas útiles
  • están diseñados para un uso mínimo de energía (y, por lo tanto, duración máxima de la batería)
  • son de largo alcance por diseño
  • tener clases de conexión (siempre activadas, reconocidas, no reconocidas)
  • tiene ventanas de descarga programadas (por ejemplo, para actualizaciones de firmware o ACK RX)

Puede conectarse a la infraestructura LoRa comercial o comunitaria existente en la mayoría de los países, o puede implementar sus propios centros LoRa si fuera más apropiado.

Existe un desarrollo activo a nivel mundial y una fácil disponibilidad de escudos de prototipos (por ejemplo, para Arduino).


1
Una vez por minuto, como se menciona en la pregunta, es demasiado frecuente para ajustarse a los intervalos recomendados de transmisión del nodo LoRa.
Chris Stratton

1
De acuerdo 1 minuto es muy a menudo. Aunque @bgusach no menciona la aplicación. Si la carga útil puede ser codificada en binario para reducir el tamaño y si se puede utilizar un intervalo de 3-5 minutos (o incluso 10 minutos), entonces podría ser ideal. De todos modos, solo una sugerencia ya que noto que no se mencionó anteriormente en las respuestas.
BrendanMcL

1
Sí, si lo estoy leyendo bien, algo así como 50 bytes a intervalos de cuatro minutos podría no ser adecuado; pero eso necesita verificación, podría fácilmente desactivarse por al menos un factor de dos.
Chris Stratton

1
Interesante, pero estamos limitados por GSM / SIM (esto pretende ser un bien para el consumidor, algo que se puede comprar y usar en cualquier lugar sin ninguna infraestructura, excepto la red telefónica).
bgusach

3

Prefiero una respuesta HTTP mínima con datos JSON ... una respuesta HTTP puede estar muy por debajo de la transferencia HTTP de 500 bytes, y sigue siendo compatible con muchos clientes para aplicaciones web RESTful.

Un mensaje HTTP mínimo (por ejemplo, con resultado JSON) con aproximadamente 130 bytes de datos HTTP se ve así:

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

si solo desea ENVIAR datos de su aplicación al servidor, simplemente puede usar un HTTP GET donde configure los parámetros de URL de lat / long. La solicitud tiene incluso menos datos que la respuesta.

GET /?lat=42.00000&long=10.0000 HTTP/1.1
Host: 192.168.0.2 
User-Agent: Proprietary
Accept: */* 
Connection: close

77
Gracias por su respuesta, pero no veo su punto con la respuesta HTTP. Queremos deshacernos de todo el Protocolo HTTP para guardar la transferencia de datos. Y además de eso, usar GETpara modificar recursos es lo Wrong Thing™que hay que hacer
bgusach

De acuerdo con usted desde el punto de vista arquitectónico, otros verbos como POST (como verbo universal) son más comunes en las API REST. Depende del nivel de madurez que esté desarrollando su API REST. Solo quería mostrar cómo se puede minimizar un HTTP, a la vez que se mantiene el beneficio de una fácil implicación y compatibilidad con los marcos existentes (cliente y servidor), y al mismo tiempo se mantiene la legibilidad humana. Responder con una muestra de respuesta fue confuso ... Si desea ENVIAR los datos, por supuesto, usaría un mensaje POST o GET, en caso de una POST, con el contenido json que mostré en mi primera muestra.
Christoph Bimminger

3

No hay un "mejor" protocolo. Solo muchas compensaciones a tener en cuenta:

  • ¿Sus dispositivos estarán en redes aleatorias con puertos aleatorios bloqueados? Si es así, podría ser mejor usar HTTPS.

  • Si envía UDP, siempre puede enviar las últimas N mediciones cada vez, de modo que se ignore la pérdida de paquetes pequeños. También puede enviar paquetes ACK, convirtiendo UDP en un protocolo confiable. (La mayoría de los protocolos sobre UDP hacen esto).

  • ¿A sus clientes les importará si sus datos se exponen sin cifrar? ¿A sus clientes les importará si los piratas informáticos pueden inyectar datos incorrectos en esas conexiones no cifradas? (Si es así, es posible que desee cifrado).

  • ¿Qué sucede si alguien huele tu protocolo y manipula los datos? ¿Se puede evitar que un dispositivo sobrescriba datos para otro?

  • ¿Cuántos dispositivos tendrás como máximo? ¿Cómo vas a lidiar con todos esos dispositivos? ¿Cómo va a enrutar los datos a donde necesita ir? ¿Cómo manejas el mantenimiento y las actualizaciones de la infraestructura de tu servidor? Si no tiene experiencia, probablemente esté sobreestimando su capacidad para manejar muchas conexiones simultáneas. Puede ser mejor subcontratar a un proveedor (y usar sus protocolos, como AWS IoT).


3

Tenemos una prueba exacta que compara la velocidad de transmisión de HTTP vs MQTT, vea test2 , en su escenario actual, MQTT le traerá 50 veces menos tráfico (y batería) que HTTP.

Básicamente no hay diferencia entre MQTT y TCP simple (en tamaño de mensaje). Incluso diría que básicamente no hay diferencia entre TCP simple y mensajes binarios y JSON en la carga útil MQTT. De esta manera, es mucho más conveniente usar MQTT + JSON y confiar en estas tecnologías para la entrega y representación de datos. Simplemente nombre sus claves más o menos cortas.

Con respecto a UDP, si la transmisión es una vez por minuto, entonces es mejor usar TCP. Si la transmisión es una vez cada 10-20 minutos o más, entonces puede considerar UDP como una solución más efectiva para el tráfico / batería. Si intenta desarrollar un protocolo propio con ACK, le recomiendo que use MQTT o TCP y que solo se concentre en su caso de negocios.

En general, cuanto más simple sea su implementación, mejores resultados podrá lograr en el menor tiempo. Si yo fuera usted, en ese caso sería mejor probar UDP + propio formato binario y MQTT + JSON y seleccionar uno de ellos. O incluso acabo de comenzar desde MQTT + JSON y luego pensar si está bien para mi caso.


1
Mencionaré aquí algunas palabras contra UDP. Mantenemos un gran sistema de gestión de flota GPS SaaS (más de 1 millón de vehículos conectados) con clientes en más de 100 países en todo el mundo. Y recientemente descubrimos que los proveedores de Internet con sede en EE. UU. Están bloqueando paquetes UDP que salen de EE. UU. Por alguna razón, incluso para aplicaciones M2M. Comenzó hace unos meses, pero es muy doloroso, por lo que te recomiendo que selecciones el protocolo basado en TCP (MQTT) y confíes en los estándares globales. Algún día y en algunos países, incluso se verá obligado a usar MQTT a través de sockets web para mantener la conexión. Solo un pequeño consejo.
shal
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.