Fundamentos de MQTT

Los 15 tipos de paquetes de control MQTT explicados

MQTT tiene solo 15 tipos de paquetes de control. Esta referencia explica cada uno, de CONNECT a AUTH, con su número de tipo, su sentido, su primer byte y cómo se ve en los registros de depuración mientras resuelves problemas.

Diagrama de secuencia de un cliente y un broker intercambiando paquetes de control MQTT de CONNECT a DISCONNECT
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

Los paquetes de control MQTT son los 15 tipos de mensaje que intercambian clientes y brokers, de CONNECT a AUTH, y toda interacción MQTT se construye con ellos. Esta referencia explica qué hace cada paquete, quién lo envía, cómo reconocerlo por su primer byte y cómo se ve en los registros de depuración del cliente, para que puedas seguir una conversación con un broker y localizar dónde falla.

Los paquetes de control MQTT de un vistazo

El tipo de paquete está en los cuatro bits altos del primer byte de cada paquete. MQTT 3.1.1 define los tipos del 1 al 14; MQTT 5 añade el tipo 15, AUTH. El tipo 0 está reservado y nunca es válido.

Tipo Nombre Sentido Primer byte Finalidad
1 CONNECT Del cliente al broker 0x10 Abrir una sesión
2 CONNACK Del broker al cliente 0x20 Aceptar o rechazar la conexión
3 PUBLISH Ambos 0x30-0x3F Entregar un mensaje de la aplicación
4 PUBACK Ambos 0x40 Confirmar una publicación QoS 1
5 PUBREC Ambos 0x50 QoS 2, paso 1: publicación recibida
6 PUBREL Ambos 0x62 QoS 2, paso 2: liberación
7 PUBCOMP Ambos 0x70 QoS 2, paso 3: completado
8 SUBSCRIBE Del cliente al broker 0x82 Solicitar suscripciones
9 SUBACK Del broker al cliente 0x90 Conceder o rechazar suscripciones
10 UNSUBSCRIBE Del cliente al broker 0xA2 Eliminar suscripciones
11 UNSUBACK Del broker al cliente 0xB0 Confirmar la baja de la suscripción
12 PINGREQ Del cliente al broker 0xC0 Sonda de keep alive
13 PINGRESP Del broker al cliente 0xD0 Respuesta de keep alive
14 DISCONNECT Del cliente al broker (ambos en MQTT 5) 0xE0 Cerrar la conexión limpiamente
15 AUTH Ambos (solo MQTT 5) 0xF0 Intercambio de autenticación mejorada

Conocer el primer byte es útil cuando lees un volcado hexadecimal en bruto: 0xC0 0x00 es un PINGREQ y 0x82 inicia un SUBSCRIBE. La disposición a nivel de byte de cabeceras y payloads se explica en la guía de estructura de los paquetes MQTT.

Ver los paquetes de control en un registro de depuración

La forma más fácil de ver estos paquetes es el flag -d de los clientes de Mosquitto. Contra el servidor MQTT público gratuito:

mosquitto_sub -h broker.connectmq.com -p 1883 -i pkt-demo-e41f \
  -t "connectmq/demo/e41f/#" -q 1 -k 10 -d

En una segunda terminal, publica un mensaje:

mosquitto_pub -h broker.connectmq.com -p 1883 -i pkt-pub-e41f \
  -t "connectmq/demo/e41f/temp" -m "22.1" -q 1 -d

La salida del suscriptor será parecida a esta:

Client pkt-demo-e41f sending CONNECT
Client pkt-demo-e41f received CONNACK (0)
Client pkt-demo-e41f sending SUBSCRIBE (Mid: 1, Topic: connectmq/demo/e41f/#, QoS: 1, Options: 0x00)
Client pkt-demo-e41f received SUBACK
Subscribed (mid: 1): 1
Client pkt-demo-e41f received PUBLISH (d0, q1, r0, m1, 'connectmq/demo/e41f/temp', ... (4 bytes))
Client pkt-demo-e41f sending PUBACK (m1, rc0)
22.1
Client pkt-demo-e41f sending PINGREQ
Client pkt-demo-e41f received PINGRESP

El keep alive -k 10 hace que aparezca un PINGREQ tras diez segundos de inactividad. En la línea del PUBLISH, d0, q1, r0, m1 significa DUP 0, QoS 1, retain 0 e ID de mensaje 1. Paho Python imprime líneas similares con client.enable_logger(), y MQTT.js lo hace con la variable de entorno DEBUG=mqttjs*.

Paquetes de conexión: CONNECT, CONNACK, DISCONNECT

CONNECT es siempre el primer paquete que envía un cliente. Lleva la versión del protocolo, el flag clean session o clean start, el keep alive, el client ID, un Last Will opcional y un usuario y una contraseña opcionales. En MQTT 5 lleva además propiedades como Session Expiry Interval, Receive Maximum y Topic Alias Maximum. Enviar un segundo CONNECT en la misma conexión es un error de protocolo.

CONNACK es la respuesta del broker. Contiene el flag Session Present y un código de retorno (3.1.1) o un reason code (MQTT 5). Los brokers MQTT 5 también usan las propiedades del CONNACK para informar al cliente de sus límites: Maximum QoS, Maximum Packet Size, Topic Alias Maximum, si están disponibles retain, comodines o suscripciones compartidas, y un client ID asignado si el cliente envió uno vacío. Cuando una conexión falla, el CONNACK es el primer sitio donde mirar; consulta códigos de retorno CONNACK de MQTT.

DISCONNECT cierra la conexión limpiamente. Un cliente que envía DISCONNECT antes de cerrar el socket suprime su mensaje Last Will (salvo en MQTT 5 con el reason code 0x04). En MQTT 3.1.1 solo el cliente envía DISCONNECT; en MQTT 5 el broker también puede enviarlo, con un reason code que explica el motivo, como 0x8E Session taken over o 0x97 Quota exceeded. Si ves un bucle de reconexión, busca DISCONNECT enviados por el broker; la guía sobre por qué un cliente MQTT se desconecta constantemente repasa las causas.

Paquetes de publicación: PUBLISH y los acuses de recibo

PUBLISH lleva el mensaje de la aplicación en cualquiera de los dos sentidos: del cliente al broker cuando publicas y del broker al cliente cuando recibes. Los flags de su cabecera fija contienen DUP, QoS y RETAIN.

Los acuses de recibo dependen del QoS, explicado a fondo en niveles de QoS de MQTT:

QoS Flujo de paquetes Paquetes totales por mensaje
0 PUBLISH 1
1 PUBLISH, PUBACK 2
2 PUBLISH, PUBREC, PUBREL, PUBCOMP 4
  • PUBACK confirma un mensaje QoS 1. Hasta que llega, el emisor conserva el mensaje y puede reenviarlo con DUP activado tras reconectarse.
  • PUBREC es el "lo tengo" del receptor en QoS 2. A partir de ahí, el emisor puede descartar el payload del mensaje.
  • PUBREL indica al receptor que puede liberar el mensaje hacia los suscriptores y que el ID de paquete podrá reutilizarse pronto.
  • PUBCOMP cierra el intercambio de QoS 2.

Ten en cuenta que cada salto es independiente. Una publicación QoS 1 de un sensor al broker y una entrega QoS 2 del broker a un suscriptor son intercambios separados. En MQTT 5 estos acuses de recibo llevan reason codes, de modo que un PUBACK puede indicar 0x10 No matching subscribers o 0x87 Not authorized.

Paquetes de suscripción: SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK

SUBSCRIBE contiene un identificador de paquete y uno o varios filtros de topic, cada uno con un QoS solicitado. MQTT 5 añade opciones de suscripción como No Local, Retain As Published y Retain Handling, además de un Subscription Identifier opcional.

SUBACK devuelve un código por filtro en el mismo orden. Lee todas las entradas: un único SUBSCRIBE con tres filtros puede tener éxito en dos y fallar en uno. En 3.1.1 el valor de fallo es 0x80; MQTT 5 da motivos concretos como 0x8F Topic Filter invalid o 0x9E Shared Subscriptions not supported.

UNSUBSCRIBE y UNSUBACK hacen lo mismo para las bajas. MQTT 5 añade reason codes por filtro a UNSUBACK, incluido 0x11 No subscription existed.

Paquetes de keep alive: PINGREQ y PINGRESP

PINGREQ y PINGRESP son paquetes de dos bytes que demuestran que la conexión sigue viva cuando no circula otro tráfico. El cliente envía PINGREQ si no ha enviado nada dentro del intervalo de keep alive; el broker debe responder con PINGRESP. Si el broker no recibe nada durante 1,5 veces el keep alive, cierra la conexión. Si el cliente no recibe PINGRESP en un tiempo razonable, debe considerar la conexión muerta. La guía del intervalo de keep alive de MQTT explica cómo elegir el valor.

AUTH: la novedad de MQTT 5

AUTH admite la autenticación mejorada, como los mecanismos de desafío-respuesta, mediante las propiedades Authentication Method y Authentication Data. Se usa después de CONNECT para intercambios de varios pasos y también puede iniciar una reautenticación en una conexión existente. La mayoría de los despliegues, incluidos los inicios de sesión con usuario y contraseña, nunca envían AUTH, así que verlo en una captura es inusual salvo que hayas configurado un método mejorado.

Lista de depuración por paquete

  1. ¿No llega el CONNACK? El problema es de red, de puerto o de TLS, no de MQTT.
  2. ¿CONNACK con un código distinto de cero? Credenciales, client ID o versión del protocolo.
  3. ¿SUBACK con 0x80 o superior? Filtro incorrecto, permisos o función no admitida.
  4. ¿PUBLISH enviado pero sin PUBACK? Comprueba el soporte de QoS y el estado de la conexión.
  5. ¿PINGREQ repetidos sin PINGRESP? La conexión está medio muerta; reconéctate.
  6. ¿DISCONNECT inesperado del broker? Lee su reason code.

Observa cada paquete en ConnectMQ

ConnectMQ admite MQTT 3.1.1 y 5.0, así que puedes observar tanto el flujo de paquetes clásico como los reason codes y propiedades de MQTT 5 contra el mismo broker. Para una visión más amplia, lee qué hace un broker MQTT con estos paquetes o sigue el tutorial de MQTT completo.

Construye sobre ConnectMQ

Cuando pases de los experimentos a los dispositivos, un broker MQTT gestionado se encarga de TLS, las credenciales y la disponibilidad. Crea un broker Serverless gratuito en app.connectmq.com sin tarjeta de crédito y usa el cliente en el navegador y el explorador de topics en directo del portal mientras depuras. También puedes comparar opciones en nuestra guía del mercado de brokers MQTT en la nube.

Preguntas frecuentes

¿Cuántos tipos de paquetes de control MQTT existen?

MQTT 5 define 15 tipos de paquetes de control, numerados del 1 al 15. MQTT 3.1.1 tiene 14, porque el paquete AUTH se añadió en MQTT 5.

¿Qué paquetes usa un mensaje QoS 2?

PUBLISH, PUBREC, PUBREL y PUBCOMP. El intercambio en cuatro pasos garantiza que el mensaje se entregue exactamente una vez entre ese emisor y ese receptor.

¿Puede el broker enviar un paquete DISCONNECT?

Solo en MQTT 5. En MQTT 3.1.1 el broker simplemente cierra la conexión de red; MQTT 5 le permite enviar antes un DISCONNECT con un reason code.

¿Por qué veo PINGREQ en mis registros?

PINGREQ es la sonda de keep alive del cliente, que se envía cuando ha estado inactivo durante el intervalo de keep alive. Los pares regulares de PINGREQ y PINGRESP son normales y muestran que la conexión está sana.

Artículos relacionados

¿Quién inventó MQTT? La historia, de los oleoductos al IoT

MQTT lo inventaron en 1999 Andy Stanford-Clark, de IBM, y Arlen Nipper, de Arcom, para monitorizar oleoductos vía satélite. Sigue su camino hacia el open source, OASIS, ISO y los brokers MQTT gestionados en la nube de hoy.

8 min de lectura

Por qué tu cliente MQTT se desconecta constantemente (y cómo solucionarlo)

Los bucles de reconexión son uno de los problemas más habituales de MQTT. Conoce las cinco causas típicas, desde los client ID duplicados hasta los timeouts de keep alive y los paquetes demasiado grandes, y sigue un flujo de diagnóstico que localiza la tuya.

9 min de lectura

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.