MQTT: un protocolo abierto de red y su importancia en el IoT

MQTT protocolo red IoT

Recuerda el nombre MQTT, ya que es un protocolo de comunicación en red tipo M2M (Machine to Machine) que va a sonar bastante. Está popularizándose bastante gracias a la nueva era del Internet de las cosas o IoT (Internet of Things) por sus siglas en inglés. Además, se trata de un protocolo abierto, lo que da bastantes ventajas.

De hecho, se ha transformado en uno de los pilares centrales del IoT, ya que es bastante bueno en dispositivos con algunas limitaciones de transmisión como éstos. Las siglas MQTT provienen de Message Queuing Telemetry Transport, un estándar abierto de OASIS e ISO (ISO/IEC 20922) para comunicaciones en red y que se ejecuta, generalmente, sobre el famoso TCP/IP.

Protocolos de red

OSI modelo y sus capas

Los protocolos de comunicación son reglas que posibilitan que dos o más dispositivos o sistemas se puedan comunicar entre sí. Es decir, es un protocolo para transmitir información a través de diversos medios y con un formato definid, ya sean implementados por software y por hardware (o ambos).

El estándar del protocolo define multitud de características de la comunicación. Puede ir desde las reglas de sincronización, semántica, sintaxis, formato de paquetes, etc. Y lo cierto es que no son algo despreciable, ya que gracias a estos protocolos hoy podemos usar Internet y otras redes de comunicación…

Y por supuesto, no solo existe un solo protocolo, sino muchos. Por ejemplo, los famosos DNS, FTP, MQTT, HTTP y HTTPS, IMAP, LDAP, NTP, DHCP, SSH, Telnet, SNMP, SMTP, etc., para la capa de aplicación. Mientras que en capa de transporte se pueden encontrar algunos tan famosos como TCP, UDP, etc., así como los de la capa de Internet como IPv4, o el IPv6 (el que ha posibilitado mayor cantidad de IPs disponibles y la llegada del IoT), IPSec, etc., y otros de la capa de enlace como DSL, Ethernet, WiFi, ARP, etc.

Sobre los protocolos de IoT

Protocolo MQTT

Por supuesto, hay protocolos de comunicación específicos o que se pueden aplicar al IoT. Es decir, visto lo del apartado anterior, serían una serie de normas definidas para que dos o más dispositivos IoT se puedan comunicar y entenderse entre sí, y por lo general son M2M, es decir, comunicación de máquina a máquina.Gracias a ellos puede haber muchos dispositivos de IoT conectados y compartiendo información de sensores o de otras fuentes.

Debido a la gran cantidad de dispositivos IoT, estos protocolos deben cumplir unos requisitos más allá de las limitaciones de ancho de banda, velocidad, etc. (ten en cuenta que muchos dispositivos son embebidos y baratos), que suele haber en algunos dispositivos. Y me refiero al hecho de que deben ser escalables, para poder agregar más dispositivos conectados si es necesario y sin que afecten al sistema global.

Además, tienen que tener una baja dependencia de acoplamiento entre dispositivos, para que no se generen problemas si se retira un dispositivo. Y por supuesto, a la par, se busca una alta interoperabilidad para que funcione con una gran cantidad de dispositivos y sistemas muy variados, ya que el mundo del IoT es bastante heterogéneo.

Otras características útiles sería la facilidad de implementarlos, la seguridad, etc. Ten en cuenta que el IoT está generando grandes desafíos en el aspecto de la seguridad. Más aún cuando muchos de los dispositivos conectados suelen ser críticos en ciertos casos…por ejemplo, juguetes de menores de edad.

Conceptos importantes

Dicho esto, hay que decir que las soluciones para el IoT usan un servidor centralizado para recibir los mensajes de todos los dispositivos conectados que emiten y los distribuye a todos los dispositivos conectados IoT que están a la escucha. Ese servidor es lo que se conoce como router o broker. Algo que dista de la relación cliente-servidor convencional en algunos sentidos.

Por otro lado, las metodologías que puedes encontrar en estos protocolos de comunicación para IoT están:

  • PubSub: Publish/Susbcribe es un patrón de mensajería donde un dispositivo (Sub) informa al broker de que quiere recibir un mensaje, mientras otro dispositivo (Pub) publica mensajes para que el broker los distribuya al otro/s dispositivo/s que los espera.
  • rRPC: Router Remoder Procedure Calls es otro patrón de ejecución remota de procesos. En él, un dispositivo (Callee) informa al broker de que realizará cirto procedimiento y el broker lo distribuye a otro dispositivo (Caller) en el que se ejecuta dicho proceso.

Ahora bien, para realizar esas metodologías o patrones, se necesitan de una infraestructura de mensajería. Y en este sentido se pueden distinguir dos:

  • Message Queue: servicio de mensajería donde se genera una sola cola de mensajes para todos los clientes que inician una subscripción en el broker. Éste último mantendrá los mensajes almacenados hasta que son entregados al cliente. Si el cliente o destinatario no estuviera conectado, se mantiene hasta que se conecta. Este tipo de servicios son como los usados en apps de mensajería instantánea como Telegra, Whatsapp, Messenger, etc.
  • Message Service: es otro servicio en el que el broker envía los menajes al cliente destinatario conectado, filtrando por el tipo de mensaje. Si el cliente o dispositivo receptor está desconectado, entonces se pierden los mensajes (aunque puede tener algún sistema de registro).

Protocolos IoT

Visto lo anterior, ahora vamos a ver un poco más de cerca los protocolos de IoT que son más conocidos. Entre los más destacados de M2M están:

  • AMQP (Advanced Message Queuing Protocol): es un protocolo de tipo PubSub de Message Queue. Diseñado para tener una buena interoperabilidad y asegurar la confiabilidad. Especial para aplicaciones corporativas, de alto rendimiento, redes de alta latencia, críticas, etc.
  • WAMP (Web Application Messaging Protocol): es otro protocolo abierto de tipo PubSub como rRPC, y se ejecuta sobre WebSockets.
  • CoAP (Constrained Application Protocol): es un protocolo diseñado especialmente para aplicaciones de baja capacidad.
  • TOMP (Streaming Text Oriented Messaging Protocol): protocolo muy simple y para conseguir la máxima interoperabilidad. Se emplea HTTP para transmitir mensajes de texto.
  • XMPP (eXtensible Messaging and Presence Protocol): otro protocolo empleado en IoT para apps de mensajería instantánea y basado en XML. Ene este caso también es abierto.
  • WMQ (WebSphere Message Queue): protocolo desarrollado por IBM. Es de tipo Message Queue, como su nombre indica, y orientado a mensajes.
  • MQTT: (véase siguiente apartado)

Todo sobre MQTT

paquete de MQTT

El protocolo MQTT es un protocolo de comunicación Message Queue, que sigue un patrón PubSub, y de tipo M2M como ya he comentado anteriormente. Se usa ampliamente en el IoT, y se basa en la pila TCP/IP usada en Internet.

En el caso de MQTT, cada conexión se mantiene abierta y se reutiliza en cada comunicación necesaria. Algo diferente a lo que ocurre en otros protocolos conocidos, que se realiza cada comunicación necesita una nueva conexión.

Ventajas

Las ventajas del protocolo MQTT son bastante evidentes en cuanto a comunicaciones M2M para IoT. Además de todo lo dicho anteriormente, es un protocolo que aporta:

  • Eescalabilidad, para conectar más y más clientes.
  • Desacoplamiento entre clientes, para menor dependencia.
  • Asincronismo.
  • Sencillez.
  • Ligereza para no consumir demasiados recursos (aunque con seguridad TLS/SSL sube).
  • Eficiencia energética para dispositivos que dependen de batería o funcionan 24/7, no necesita de un gran ancho de banda (ideal para conexiones lentas, como algunas inalámbricas).
  • Seguridad y calidad, para mayor fiabilidad y robustez en comunicaciones.

Historia

MQTT fue creado en los años 90, con una primera versión del protocolo en 1999. Fue creado por el Dr. Andy Stanford-Clark de IBM y Arlen Nipper de Cirrus Link (anteriormente Eurotech).

La idea inicial era crear un protocolo para monitorear un oleoducto que viajaba a través del desierto, con un protocolo de comunicación eficiente (consumo bajo de ancho de banda), liviano, y que un bajo consumo energético. En ese momento fue muy costoso, pero ahora se ha transformado en un protocolo barato y abierto.

El protocolo inicial fue mejorado con la aparición de nuevas versiones, como la MQTT v3.1 (2013) bajo la especificación OASIS (Organization for the Advancement of Structured Information Standards), etc. Debes saber que al principio era un protocolo propietario de IBM, pero que sería liberado en 2010, y se terminó transformando en estandar en OASIS…

Funcionamiento de la conexión MQTT

El protocolo MQTT usa un filtro, para los mensajes que son enviados a cada cliente, basado en topics o temas que se organizan de forma jerárquica. De ese modo, un cliente puede publicar un mensaje en un topic concreto. De ese modo, todos aquellos clientes o dispositivos conectados que se suscriban al topic, recibirán mensajes por medio del broker.

Como es MQ, los mensajes se mantendrán en la cola y no se pierden hasta que el cliente no ha recibido dicho mensaje.

Las conexiones, como también indiqué, se realizan por medio de TCP/IP, y el servidor o broker mantendrá un registro de los clientes conectados. Por defecto, los dispositivos emplearán puertos de comunicación número 1883, aunque también puedes encontrarte con un puerto 8883 si está usando SSL/TLS para mayor seguridad.

Para que la conexión sea posible, no solo se necesitan clientes, servidor y puertos. También otros paquetes o mensajes enviados para que la comunicación se realice:

  • Establecer conexión: mensaje/paquete CONNECT enviado por el cliente con toda la información necesaria. Esa información incluye el ID del cliente, el nombre de usuario, contraseña, etc. El broker o servidor responde con un paquete CONNACK que informará al cliente de que la conexión fue aceptada, rechazada, etc.
  • Enviar y recibir mensajes: una vez establecida la conexión se usan paquetes o mensajes PUBLISH con el topic o tema y el payload del mensaje enviado al broker. Por otro lado, el cliente o clientes interesados usan paquetes SUBSCRIBE y UNSUSCRIBE para suscribirse o retirar su suscripción respectivamente. El broker responderá también con un paquete SUBACK y UNSUBACK respectivamente para informar del éxito de la operación demandada por el cliente.
  • Mantenimiento de la conexión: para garantizar que la conexión sigue abierta, los clientes pueden mandar periódicamente un paquete PINGREQ que será correspondido con un paquete PINGRESP del servidor.
  • Finalizar conexión: cuando un cliente se desconecta envía un paquete DISCONNECT para informar de ese evento.

Esos mensajes o paquetes de los que he hablado tienen una estructura igual que otros paquetes de otros protocolos de red:

  • Header o cabecera fija: es una parte fija que ocupa entre 2-5 bytes. Contiene un código de control, ID del tipo de mensaje enviado, y su longitud. Entre 1-4 bytes son usados para la codificación de la longitud, usando los 7 primeros bits de cada octeto como dato para la longitud y un bit adicional de continuidad para determinar que hay más de un byte que componen la longitud del mensaje.
  • Cabecera variable: no es siempre obligatoria, sino opcional. Solo la contienen algunos paquetes en ciertas situaciones o mensajes concretos.
  • Contenido o data: los datos del paquete son los que realmente contienen el mensaje que se pretende enviar. Puede tener desde unos cuantos kB hasta 256 MB de límite.

Si te interesa conocer el código correspondiente en hexadecimal para los tipos de mensajes enviados son:

Mensaje Código
CONNECT 0x10
CONNACK 0x20
PUBLISH 0x30
PUBACK 0x40
PUBREC 0x50
PUBREL 0x60
PUBCOMP 0x70
SUSBSCRBE 0x80
SUBACK 0x90
UNSUSCRIBE 0xA0
UNSUBACK 0xB0
PINGREQ 0xC=
PINGRESP 0xD0
DISCONNECT 0xE0

Calidad y seguridad de las comunicaciones

Otro detalle importante de los mensajes por MQTT es la calidad del servicio o QoS, y la seguridad. De ello dependerá la robustez del sistema de comunicación ante fallos y la seguridad del mismo.

En cuanto a su calidad se pueden determinar 3 niveles diferentes:

  • QoS 0 (unacknowledge): el mensaje solo se envía una vez, y en caso de fallo no se entregaría. Se usa cuando no es crítico.
  • QoS 1 (acknowledge): el mensaje se enviará tantas veces como se necesite hasta garantizar la entrega al cliente. Lo malo es que el cliente podría recibir varias veces un mismo mensaje.
  • QoS 2 (assured): similar al anterior, pero se garantiza que solo se entrega una única vez. Se suele usar para sistemas más críticos donde se necesita mayor fiabilidad.

Por otro lado, en cuanto a la seguridad de MQTT, se pueden usar varias medidas para garantizar su fortaleza en este sentido. Como ya he comentado antes, la autonticación del usuario y contraseña, como otros muchos protocolos, se puede asegurar mediante SSL/TLS. Aunque muchos dispositivos IoT con capacidades, o recursos bajos, podrían tener problemas con la sobrecarga de trabajo al usar este tipo de comunicación segura…

Por ese motivo, muchos aparatos IoT que usan MQTT usan contraseñas y usuarios en texto plano, lo que podría hacer que alguien en esnife el tráfico de red las pueda obtener de forma muy fácil. Y si eso es poco, también se puede configurar el broker para aceptar conexiones anónimas, lo que permitiría a cualquier usuario establecer comunicaciones, implicando mayor riesgo.

Usar MQTT con Arduino

Arduino UNO con MQTT

Por supuesto, puedes usar el protocolo MQTT con Arduino y otras placas de desarrollo, así como con la Rapsberry Pi, etc. Para ello, debes dotar a tu placa Arduino de conectividad, si no la tiene. Además, la biblioteca Arduino Client for MQTT te ayudará en estas tareas. Ésta biblioteca es compatible con:

Ya sabes que puedes descargar e instalar la biblioteca en tu Arduino IDE usando el comando: git clone https://github.com/knolleary/pubsubclient.git

En cuanto al código para usar MQTT en alguna aplicación, la verdad es que es sencillo. En la imagen de Fritzing puedes ver una placa Arduino UNO a la que se le ha agregado conectividad por Arduino Ethernet y también se ha conectado un sensor de humedad y temperatura DHT22, aunque podría haber sido cualquier otra cosa…

Bien, dicho esto, para el código que tienes que generar en Arduino IDE para trabajar con el protocolo MQTT en Arduino, es así de simple:

  • Para enviar mensajes MQTT

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <DHT.h>

#define DHTPIN 2
#define DHTTYPE DHT22

// Direccion MAC del adaptador Ethernet
byte mac[] = { 0xCE, 0xAB, 0x0E, 0x3F, 0xFE, 0xD4 };

// IP del servidor (broker)
IPAddress mqtt_server(192, 168, 1, 4);

// Topic o tema con el que se trabaja
const char* topicName = "test";

DHT dht(DHTPIN, DHTTYPE);
EthernetClient ethClient;
PubSubClient client(ethClient);

void setup()
{
  Serial.begin(9600);
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Fallo en Ethernet usando DHCP");
  }
// Puerto 1883 de comunicación
  client.setServer(mqtt_server, 1883);
  dht.begin();
}

void loop()
{
  if (!client.connected()) {
    Serial.print("Conectando ...\n");
    client.connect("Cliente Arduino");
  }
  else {
    // Envío de informacion del sensor de temperatura y humedad
    float temp = dht.readTemperature();
    char buffer[10];
    dtostrf(temp,0, 0, buffer);
    client.publish(topicName, buffer);
  }
  // Tiempo entre envíos en ms (cada 10 segundos)
  delay(10000);
}

  • Para recibir mensajes por MQTT solo necesitas la placa Arduino UNO y conexión, con Arduino Ethernet o cualquier otro elemento. En cuanto al código, un ejemplo sería:

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

// Direccion MAC del adaptador Ethernet
byte mac[] = { 0xCE, 0xAB, 0x0E, 0x3F, 0xFE, 0xD4 };

// IP del servidor (broker)
IPAddress mqtt_server(192, 168, 1, 4);

// Topic o tema con el que trabajr
const char* topicName = "test";

EthernetClient ethClient;
PubSubClient client(ethClient);

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("El mensaje ha llegado [");
  Serial.print(topic);
  Serial.print("] ");
  int i=0;
  for (i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void setup()
{
  Serial.begin(9600);
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Fallo en Ethernet al usar configuración DHCP");
  }
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback)
}

void loop()
{
  if (!client.connected()) {
      Serial.print("Conectando ...");
      if (client.connect("rece_arduino")) {
        Serial.println("conectado");
        client.subscribe(topicName);
      } else {
        delay(10000);
      }
  }
  // Cliente a la escucha
  client.loop();
}

Recuerda que deberás cambiar la IP por la adecuada del servidor, y también debes alterar la dirección MAC de tu adaptador de red Ethernet o el que estés usando, así como el resto de código si pretendes adaptarlo a un proyecto diferente. ¡Esto es solo un ejemplo!

Para más información, puedes descargar de forma gratuita nuestro manual en PDF con el curso de Arduino IDE para iniciar a la programación.


Sé el primero en comentar

Deja tu comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.