Guía completa del protocolo MQTT: Desde lo básico hasta las aplicaciones industriales
Actualizado: 12 oct

Una bomba remota puede enviar su temperatura a un panel de mantenimiento sin dar al panel acceso directo al PLC. MQTT permite transportar ese valor: un cliente publica un mensaje en un broker y los suscriptores autorizados reciben mensajes de los temas correspondientes. El protocolo no define qué significa el valor, no lee por sí solo un registro Modbus ni estabiliza una conexión celular.
Antes de elegir ajustes MQTT, identifique la fuente de cada dato, el publicador, el broker, los suscriptores y la decisión que se tomará con el valor. La especificación MQTT 5.0 define el comportamiento del protocolo; las funciones del equipo y el significado de los datos deben verificarse aparte.
Introducción
Esta guía recorre el propósito de MQTT, el flujo de mensajes, la arquitectura del broker, los temas, la semántica de entrega y las funciones de MQTT 5. También explica cómo evaluar seguridad, sesiones, bibliotecas cliente e integraciones industriales según el despliegue concreto.
MQTT 3.1.1 y MQTT 5.0 son versiones distintas con propiedades y mecanismos de diagnóstico diferentes. OASIS define su comportamiento; la disponibilidad de cada función depende de que el broker, la biblioteca cliente y el firmware la admitan.
¿Qué es el protocolo MQTT?
MQTT (Message Queuing Telemetry Transport) es un protocolo de mensajería cliente-servidor basado en publicación/suscripción. Un cliente publica mensajes en temas y otros clientes se suscriben a filtros; un broker recibe las publicaciones y distribuye las que coinciden con las suscripciones autorizadas.
MQTT suele transportarse sobre una conexión TCP de larga duración. Cada paquete tiene una cabecera fija cuyo campo Remaining Length usa codificación de longitud variable; puede incluir además una cabecera variable y un payload. El tamaño total depende del tipo de paquete, la versión, el tema, las propiedades y el payload.
Filosofía de diseño y características clave de MQTT
MQTT separa productores y consumidores e incluye niveles de entrega y mecanismos de estado de conexión. Cada función cubre una parte del intercambio; ninguna convierte por sí sola la confirmación del protocolo en prueba de que una aplicación o una máquina completó una acción.
Publicación/suscripción: los productores publican en nombres de tema concretos y los consumidores solicitan filtros; no necesitan una conexión directa entre sí.
QoS: los niveles 0, 1 y 2 describen la entrega del intercambio MQTT entre emisor y receptor. No confirman que el consumidor ejecutó una acción.
Sesiones: la conservación del estado depende de la versión, los identificadores, los parámetros de sesión y las políticas y límites del broker.
TLS: puede proteger el transporte entre cliente y broker si ambos extremos configuran y validan la confianza; no sustituye la autenticación ni los permisos por tema.
MQTT normalmente usa una conexión TCP ordenada, mientras que CoAP parte de un modelo de datagramas; ninguno ofrece por sí solo una latencia determinada. MQTT 3.1 es una versión heredada, MQTT 3.1.1 se convirtió en estándar OASIS en 2014 y MQTT 5.0 en 2019. MQTT 5 añade, entre otras funciones, propiedades y códigos de razón más detallados.
¿Por qué MQTT es útil en IoT/IIoT?
El modelo de publicación/suscripción puede resultar útil cuando sensores, pasarelas o aplicaciones intercambian lecturas y eventos a través de redes limitadas o intermitentes. El consumo de memoria, el tráfico y la respuesta dependen de la biblioteca, el sistema operativo, TLS, los tamaños de mensaje, la frecuencia y la configuración. En una instalación de alumbrado, por ejemplo, la pasarela tendría que adquirir las lecturas y publicar los datos; MQTT no reemplaza esas tareas ni garantiza que un comando se ejecute.
Principios básicos y flujo de trabajo de MQTT
Un publicador envía una publicación a un tema concreto. Por separado, cada suscriptor se conecta al broker y solicita uno o varios filtros; el broker compara las publicaciones con los filtros autorizados y las entrega según la suscripción y el QoS aplicable. Las publicaciones y suscripciones son intercambios distintos; el estado de sesión y la persistencia dependen de la versión y la configuración.
Modelo Publicar/Suscribir y flujo de mensajes MQTT
La diferencia clave está entre el nombre concreto usado para publicar y los filtros usados para suscribirse. El broker proporciona la coincidencia y la entrega de mensajes, sujeto a permisos y a la versión y configuración compatibles; MQTT no exige un árbol de temas, una estructura de datos ni un algoritmo de enrutamiento determinados.
Conectar: el publicador y el suscriptor abren conexiones independientes con identificadores y versiones de protocolo compatibles; la autenticación depende de la configuración.
Suscribirse: el cliente receptor envía SUBSCRIBE con uno o varios filtros y QoS solicitado; el broker responde con el nivel concedido.
Publicar y comparar: el publicador envía PUBLISH a un tema concreto. El broker aplica los filtros, permisos y opciones de suscripción admitidos.
Entregar: el broker reenvía las publicaciones coincidentes. Las suscripciones compartidas de MQTT 5 pueden distribuir mensajes entre miembros, pero no imponen un planificador round-robin.
La distribución uno-a-muchos permite que varios suscriptores autorizados reciban publicaciones que coincidan con sus filtros, según la capacidad y configuración del broker. El broker también es una dependencia operativa que debe incluirse en el diseño de disponibilidad. Por ejemplo, una ECU o pasarela de un vehículo podría publicar vehicle/engine/rpm para que el tablero y un servicio de análisis reciban el dato; esto no establece sincronización ni capacidad para un número fijo de consumidores.
Siga un dato a través del broker
Suponga que una pasarela lee la temperatura de una bomba de un registro PLC documentado. Valida el valor, le añade una marca de tiempo y lo publica en site1/pump01/telemetry/temperature; un servicio de supervisión se suscribe a ese tema. La guía de sensores, PLC y Modbus explica por qué la pasarela debe conocer el mapa de registros. Un router que solo reenvía paquetes IP no convierte automáticamente Modbus a MQTT.
Seguir paquetes y suscripción reales
El publicador se conecta al broker con un identificador de cliente y parámetros negociados y envía PUBLISH a un tema. El suscriptor se conecta por separado y solicita con SUBSCRIBE uno o varios filtros; el broker compara mensajes y los reenvía según permisos y QoS. No genera el valor del PLC. En el ejemplo de la bomba registre el registro de origen, conversión del payload e identidad del cliente además del tema. Si el panel no muestra nada, revise en orden lectura, publicación, aceptación del broker y coincidencia del filtro.
Si el propio router recopila y publica los datos, consulte el diagnóstico de la tarea de publicación cuando dejen de llegar mensajes nuevos.
El enrutamiento de paquetes no lee un registro PLC ni lo convierte en payload MQTT. Asigne la adquisición, el mapeo y la publicación a componentes documentados.
Estructura detallada de los paquetes MQTT
Un paquete de control MQTT tiene una cabecera fija y, según el tipo de paquete y la versión, puede incluir una cabecera variable y un payload. La cabecera fija incluye el tipo y los indicadores correspondientes, además de Remaining Length, que se codifica en uno o más bytes. CONNECT, PUBLISH y PINGREQ son ejemplos de paquetes de control; el tamaño de un PUBLISH depende de sus campos y contenido.
MQTT 3.1, 3.1.1, 5.0: Diferencias entre versiones y guía de migración
Compare las versiones admitidas por cada extremo antes de cambiar una función. La versión disponible depende del broker, la biblioteca cliente y el firmware; la compatibilidad del payload, la autenticación y el estado de sesión también debe comprobarse.
Versión | Año o situación | Comportamiento principal | Diferencia relevante | Consideraciones para la migración |
|---|---|---|---|---|
3.1 | Versión heredada anterior a 3.1.1 | Publicación/suscripción y niveles QoS de la versión | Precede a 3.1.1; las particularidades dependen de la implementación heredada | Verifique las versiones de cliente y broker, la seguridad disponible y los contratos de temas y payloads. |
3.1.1 | Estándar OASIS (2014) | QoS 0–2, Clean Session, Keep Alive y Will | Consolida y aclara el comportamiento de MQTT 3.x; no incluye las propiedades de MQTT 5 | Puede ser necesaria para equipos existentes; pruebe sesión, autenticación y reconexión. |
5.0 | Estándar OASIS (2019) | Propiedades, códigos de razón, opciones de suscripción y caducidad | Añade controles de sesión, mensaje y diagnóstico respecto de 3.1.1 | Confirme soporte en cada extremo y evalúe los cambios de sesión, propiedades y errores. |
MQTT 3.1.1 puede seguir siendo adecuado para equipos instalados que solo admiten esa versión; MQTT 5 aporta funciones concretas cuando todos los extremos las soportan. Para migrar, inventaríe las versiones, temas, payloads, identidad, ACL y estado de sesión; confirme el modo compatible del broker y actualice los clientes de forma controlada. Valide el comportamiento de cada función en lugar de suponer un ahorro.
Escenarios de aplicación de MQTT en IoT (Integración detallada Modbus/MQTT/OPC UA)
MQTT puede distribuir datos de aplicaciones y pasarelas, pero la adquisición o conversión de protocolos de campo requiere un componente configurado para ello:
Modbus/MQTT: un colector configurado lee registros Modbus RTU documentados, aplica tipos y escalas y publica un payload acordado en un tema, por ejemplo plc/holding/001. Un parque eólico es un ejemplo de esta arquitectura; no se atribuye una latencia sin medición.
OPC UA/MQTT: una integración puede usar OPC UA Pub/Sub sobre MQTT cuando los perfiles, endpoints, certificados y permisos se configuran y son compatibles. El intercambio de certificados no es automático.
MQTT-SN: es un protocolo distinto dirigido a redes de sensores y puede representar temas mediante identificadores cortos. No es una versión de MQTT ni garantiza un porcentaje concreto de ahorro.
Arquitectura detallada del protocolo MQTT
En una implementación habitual, los clientes se conectan a un broker mediante MQTT sobre TCP/IP; TLS se configura para proteger el transporte. Los puertos 1883 y 8883 son ejemplos convencionales, no puertos obligatorios ni prueba de que un listener esté protegido. WebSocket u otros transportes requieren soporte y configuración específicos.
Implementación interna del modelo Publicar/Suscribir
El broker mantiene el estado necesario para suscripciones y compara nombres de tema con filtros. Puede implementar esa tarea con árboles, índices, cachés u otras estructuras; MQTT especifica el comportamiento observable, no un árbol de prefijos, una tabla hash ni una tasa de mensajes.
Funciones, tipos y diseño de alta disponibilidad del Broker
Entre las responsabilidades que puede ofrecer un broker están:
Enrutamiento y entrega: comparar filtros autorizados, aplicar opciones de suscripción y gestionar los intercambios QoS correspondientes.
Estado de sesión y mensajes: conservar el estado que permita la política elegida, dentro de las cuotas, límites, almacenamiento y vencimientos del broker.
Extensiones: algunos productos ofrecen plugins o motores de reglas; sus funciones y condiciones son específicas del producto.
Opciones de despliegue:
Un broker de nodo único, de código abierto o comercial, puede servir cuando su capacidad, mantenimiento y recuperación cumplen los requisitos del sitio.
Un servicio redundante o en clúster requiere verificar replicación, conmutación, sesiones, mensajes pendientes, publicaciones retenidas y compatibilidad de clientes; la etiqueta empresarial no garantiza la migración ni un porcentaje de disponibilidad.
Para alta disponibilidad, trace cómo la conmutación afecta a conexiones, autenticación, suscripciones, mensajes QoS pendientes y datos retenidos. Un equilibrador, un par activo/reserva o un puente entre brokers no garantiza por sí solo que las sesiones migren; compruebe el comportamiento documentado del producto y el flujo real de reconexión.
Estructura, reglas y mejores prácticas de los Tópicos
MQTT usa cadenas de tema UTF-8 con niveles separados por barras. Los nombres de tema y los filtros distinguen mayúsculas y minúsculas y deben respetar las restricciones de codificación del protocolo y los límites acordados por el producto. Diseñe también permisos que correspondan a esos niveles.
Un broker puede exponer temas de sistema como $SYS/; su existencia y contenido dependen de la implementación.
En filtros de suscripción, + coincide con un nivel y # con varios niveles finales; por ejemplo, home/+/temp o home/#.
Los publicadores envían a un nombre de tema concreto, no a un filtro con comodines. Los permisos deben limitar qué filtros y temas puede usar cada identidad.
Elija una jerarquía coherente por función, sitio, equipo y métrica, por ejemplo telemetry/site1/line2/sensor3/temp. En un almacén, inventory/warehouseA/shelfB/itemC/stock podría distinguir el inventario por ubicación; documente el propósito de cada nivel y aplique las ACL correspondientes. No existe un límite universal de 100 caracteres.
Organice los temas por sitio, activo, finalidad del mensaje y responsable. Separe telemetría y órdenes, por ejemplo site1/pump01/telemetry/... y site1/pump01/command/.... Un tema es una cadena para dirigir mensajes, no un esquema de datos ni una política de permisos. Documente campos, unidades, origen de la marca de tiempo, indicadores de calidad y versiones por separado. Si falta una medida o llega tarde, el consumidor necesita una regla para ello.
Diseñar filtros de temas y permisos juntos
Un tema tiene niveles separados por barras. El suscriptor puede usar + para un nivel y # para el resto; el publicador envía a un tema concreto sin comodines. Use nombres coherentes de sitio y activo y no incluya secretos. Defina ACL para cada rol: publicador de telemetría, suscriptor de panel y otro publicador de comandos. Pruebe un filtro autorizado y otro prohibido. Una suscripción amplia como site/# puede exponer más equipos de los que necesita el operador.
Explicación de los niveles de Calidad de Servicio (QoS) (Mecanismo, rendimiento y guía de selección)
QoS describe la entrega del protocolo en un intercambio emisor-receptor. La publicación del cliente al broker y cada entrega del broker al suscriptor son intercambios separados; el QoS concedido a una suscripción y el QoS de la publicación influyen en cada tramo. Una confirmación MQTT no demuestra que una aplicación procesó el valor o que un PLC ejecutó una acción.
Nivel QoS | Semántica de entrega | Intercambio MQTT | Consideraciones de estado y tráfico | Usos y riesgos |
|---|---|---|---|---|
0 | Como máximo una vez; la publicación puede no llegar | PUBLISH; no hay confirmación MQTT | Menos intercambio de control, pero sin confirmación de entrega | Telemetría donde una muestra perdida sea aceptable; riesgo de pérdida. |
1 | Al menos una vez en el intercambio; puede haber duplicados | PUBLISH y PUBACK | Se permiten retransmisiones; el consumidor debe tolerar o deduplicar duplicados cuando corresponda | Actualizaciones y eventos; evalúe la idempotencia y el procesamiento repetido. |
2 | Exactamente una vez dentro del intercambio QoS 2 | PUBLISH, PUBREC, PUBREL y PUBCOMP | Mantiene más estado e intercambios de protocolo; el número y el tiempo dependen de la red y las retransmisiones | Use cuando se necesite esta semántica de protocolo; no garantiza que una acción de aplicación ocurra una sola vez. |
Elija QoS para cada tipo de mensaje según las consecuencias de pérdida, duplicación y retraso. No hay un QoS predeterminado, una cuota universal para QoS 2 ni una garantía de pérdida de aplicación igual a cero. Pruebe con las versiones, el broker, la red y el consumidor del despliegue.
Elija QoS según las consecuencias de pérdidas y duplicados
MQTT ofrece QoS 0, 1 y 2. QoS 0 envía una vez sin confirmación a nivel de protocolo. QoS 1 usa confirmación y puede entregar un duplicado. QoS 2 emplea un intercambio de cuatro pasos para evitar duplicados dentro de ese intercambio MQTT. Ninguno demuestra que una aplicación posterior haya procesado el mensaje una sola vez o que se haya ejecutado una acción del PLC.
Uso | Pregunta inicial | Comprobación de aplicación |
|---|---|---|
Telemetría frecuente | ¿Puede la siguiente muestra sustituir una perdida? | Detectar huecos y marcas de tiempo antiguas |
Alarma o evento | ¿Se requieren reintentos y puede eliminar duplicados el consumidor? | Asignar ID al evento y verificar el procesamiento |
Orden de control | ¿Se ha autorizado MQTT como ruta de control del sitio? | Autorizar remitente, rechazar órdenes antiguas y confirmar el resultado real |
QoS 2 no es un ajuste universal de seguridad. Añade estado y tráfico; siguen importando los reintentos, la sesión y el procesamiento de la aplicación.
Registre por qué cada tipo de mensaje usa su QoS y pruébelo por la conexión celular real.
Interpretar confirmaciones en su límite
Con QoS 1, PUBACK confirma un paso de MQTT; reintentos pueden entregar duplicados. QoS 2 añade un intercambio para la entrega exactamente una vez dentro de ese intercambio de protocolo, con más estado y paquetes. Ninguna confirmación prueba que el panel se actualizó o que el PLC ejecutó una acción. Use identificador de aplicación y regla de deduplicación si repetir el procesamiento tiene consecuencias. Para telemetría decida si perjudica más pérdida, duplicación o cola retrasada y pruebe con enlace celular interrumpido.
Gestión de sesiones (Persistencia y control del ciclo de vida)
El estado de sesión comienza con CONNECT, el identificador del cliente y los parámetros que defina la versión. Mantenga estable el identificador de la misma instancia lógica cuando vaya a reanudar una sesión y evite compartirlo entre dispositivos activos distintos. La reanudación solo funciona si el broker conserva el estado y el cliente usa los parámetros compatibles.
MQTT 3.1.1: Clean Session indica si se inicia una sesión limpia o si se solicita conservar y reanudar el estado, sujeto al soporte y almacenamiento del broker.
MQTT 5: Clean Start determina si se inicia una sesión nueva; Session Expiry Interval indica cuánto puede conservarse el estado al desconectarse. Message Expiry Interval se aplica a un mensaje.
Keep Alive establece el intervalo de control esperado. El comportamiento de desconexión se define por el protocolo y el broker; no existe un rango universal de 20 a 1200 segundos.
Defina los límites de cola, tamaño de mensaje, almacenamiento y vencimiento según la frecuencia de publicación, la duración de los cortes y la memoria disponible. Una sesión persistente no equivale a almacenamiento offline ilimitado ni garantiza recuperar toda la telemetría después de una interrupción; pruebe también la caducidad y el reinicio del broker.
MQTT 5.0 dispone de controles de caducidad de sesión y mensajes. Su efecto depende del cliente, broker y suscripción. Pruebe qué queda en cola durante la desconexión del sitio y qué llega al reconectar. Defina cómo se tratan mensajes tardíos, duplicados y orden. Para una variable cambiante puede ser más útil una lectura nueva que una cola antigua.
Definir el ciclo de vida de la sesión
Identificador de cliente, Clean Start y Session Expiry influyen en si suscripción y estado QoS pendientes sobreviven a una reconexión. Una sesión persistente no significa almacenamiento offline ilimitado: siguen vigentes cuotas, política del broker y vencimiento de mensajes. Determine cuánto tiempo debe acumular muestras una bomba desconectada y si el consumidor precisa todas o una lectura nueva. Pruebe cortes breves y largos y, si procede, reinicio del broker; anote límites de cola reales.
Aplicación y limpieza de los Mensajes Retenidos (Retained Messages)
Una publicación con Retain puede conservar en el broker el último mensaje retenido para un tema y entregarlo a nuevas suscripciones coincidentes según sus opciones. Es una copia de la última publicación retenida, no una lectura de proceso necesariamente reciente. Para borrarla, publique un mensaje retenido con payload de cero bytes. Retain As Published es una opción de suscripción distinta; el almacenamiento y la caducidad dependen del broker y de los parámetros de MQTT 5.
Trate los mensajes retenidos, las sesiones y las desconexiones
Una publicación retenida deja en el broker el último mensaje retenido de su tema, que puede entregarse a un nuevo suscriptor. Es útil para algunos indicadores de estado, pero el valor puede ser antiguo. Añada marca de tiempo y regla de validez; no interprete una orden retenida como instrucción nueva. Un mensaje Last Will puede avisar de una desconexión imprevista, pero no demuestra que la máquina haya fallado.
Implementación e integración con monitorización del Testamento (Last Will and Testament - LWT)
El cliente puede registrar en CONNECT un Will con tema, payload, QoS y opción Retain. El broker lo publica según las condiciones de desconexión y sesión del protocolo; MQTT 5 también admite Will Delay. Un Will puede indicar que se perdió la conexión MQTT, pero no prueba por sí solo una avería física. Por ejemplo, una aplicación podría publicar { "status": "offline", "timestamp": "<ISO 8601>" }; compare la marca temporal con un heartbeat y el estado de proceso antes de mostrar el dato como actual.
Tratar el Will como señal de conexión
Un cliente puede registrar un Will al conectarse; el broker lo publica si la conexión termina inesperadamente según la configuración. Señala pérdida de conexión MQTT, no necesariamente avería física de la máquina. Combínelo con fechas y un heartbeat o regla de calidad cuando importe la frescura. Desconexión limpia y corte de red producen comportamientos distintos. Pruebe ambos y evite que un Will tardío sobrescriba un estado sano más reciente.
Un mensaje retenido es la última publicación retenida y un Will señala una condición de conexión. Use marcas temporales y evidencia de aplicación para establecer el estado actual del proceso.
Nuevas características de MQTT 5.0
MQTT 5 añade propiedades, más códigos de razón y controles de sesión, mensajes y suscripciones frente a MQTT 3.1.1. La utilidad práctica depende de las funciones que admitan el broker, la biblioteca cliente y el firmware; no se deduce de ello un porcentaje de mejora ni una cantidad universal de funciones.
Propiedades de Usuario (User Properties)
User Properties transporta pares clave/valor UTF-8 en los paquetes que permiten esa propiedad, por ejemplo un atributo de ubicación acordado. La aplicación debe definir su significado, tamaño y tratamiento; estas propiedades no cambian el QoS ni garantizan que los motores de reglas las interpreten. En versiones anteriores, la aplicación podía incluir metadatos en el payload.
Códigos de Razón (Reason Codes)
MQTT 5 proporciona códigos de razón específicos de cada paquete y puede aportar información de diagnóstico adicional. Interprete cada código según el paquete y la operación: 0x92 significa Packet Identifier not found; 0x95 significa Packet too large. Registre el contexto técnico necesario sin guardar credenciales ni afirmar una reducción de tiempo de diagnóstico.
Usar diagnósticos MQTT 5 solo si son compatibles
MQTT 5 añade códigos de motivo y propiedades para investigar conexiones, suscripciones y publicaciones rechazadas. Message Expiry Interval puede limitar la vida de un mensaje en cola y Session Expiry Interval conservar temporalmente estado de sesión. User Properties y alias de temas son opciones, no sustituyen un esquema documentado. Verifique versión y configuración compatibles en broker, biblioteca cliente y firmware del router. Lea el código real antes de cambiar firewall o credenciales.
Opciones de suscripción y filtrado avanzado
Las suscripciones compartidas usan la forma $share/{nombre-del-grupo}/{filtro} cuando el broker la admite. Reparten mensajes coincidentes entre miembros, pero el estándar no exige un orden round-robin concreto.
No Local evita que un cliente reciba ciertas publicaciones propias en las condiciones definidas por MQTT 5. Retain Handling determina cuándo se envían mensajes retenidos al suscribirse; Retain As Published controla la bandera entregada.
Subscription Identifier permite asociar una publicación recibida con una suscripción identificada. Compruebe el soporte de la biblioteca y del broker.
Comparación de funciones seleccionadas entre MQTT 5.0 y 3.1.1:
Función | Situación en MQTT 3.1.1 | Función de MQTT 5.0 | Beneficio y límites que evaluar |
|---|---|---|---|
User Properties | No ofrece esa propiedad de paquete; la aplicación puede definir campos en el payload. | Pares clave/valor en tipos de paquete que permiten la propiedad. | Acordar esquema, tamaño y codificación; el coste en bytes depende de cada mensaje. |
Códigos de razón | Códigos de retorno y respuestas de 3.1.1. | Códigos específicos en más intercambios y paquetes. | Pueden precisar el contexto de un rechazo si la biblioteca los expone; no prueban una reducción del tiempo de depuración. |
Topic Alias | No está definido. | Mapeo negociado por conexión y dirección para representar nombres de tema. | Puede reducir texto repetido; depende del soporte, del mapeo y de los temas usados. |
Suscripciones compartidas | No están definidas en 3.1.1. | Forma $share/{grupo}/{filtro}, si la implementación la admite. | Distribuyen mensajes entre miembros; escala y planificación dependen del broker y de la carga. |
Otras características: Solicitud-Respuesta y caducidad de mensajes
En MQTT 5, Response Topic y Correlation Data permiten que una aplicación relacione una solicitud con su respuesta. Son un patrón de aplicación, no una llamada RPC síncrona ni una garantía de que la operación solicitada tuvo éxito. Message Expiry Interval limita cuánto tiempo puede seguir siendo válida una publicación para entrega; confirme el comportamiento del broker.
En una actualización industrial ilustrativa, las suscripciones compartidas podrían distribuir la lectura de telemetría entre varios consumidores y Topic Alias podría abreviar nombres repetidos en una conexión MQTT 5 compatible. Compruebe la implementación y mida el mismo workload antes de estimar efectos sobre caudal, latencia o ancho de banda; no se afirma aquí un resultado de fábrica.
Cómo implementar transmisión segura con MQTT
Evalúe la exposición de clientes, red, broker y aplicación. La escucha, suplantación, acceso a temas no autorizados, payloads maliciosos y agotamiento de recursos requieren controles distintos. TLS puede proteger el transporte con confianza y verificación del servidor configuradas; autenticación y ACL dependen del producto y del despliegue.
Mecanismos de cifrado (Pasos de despliegue TLS/mTLS)
Configure un listener TLS compatible con el broker e indique host, puerto, cadena de certificados y versiones aceptadas. TLS 1.3 y el puerto 8883 son opciones de despliegue; no implican un tiempo fijo de handshake.
Emita y rote certificados mediante una CA. Verifique SAN para el nombre DNS o la dirección IP que use el cliente, junto con la cadena de confianza y el nombre del servidor. Configure el listener y el trust store del cliente; no desactive la verificación para resolver fallos.
mTLS puede autenticar a pares que presenten certificados cuando ambos lados configuran autoridades, claves y validación compatibles. No vincula automáticamente la identidad a una dirección MAC ni concede permisos MQTT. Mida el coste de handshake y cifrado en el dispositivo y la red elegidos.
Autenticación y Autorización (Control detallado con ACL)
Usuario y contraseña: use el mecanismo de gestión de credenciales admitido por el broker y transporte protegido. MQTT no prescribe un formato de almacenamiento como SHA-256.
Identidad externa: JWT u OAuth 2 pueden integrarse mediante el broker, un plugin o un servicio de identidad compatible; MQTT 5 no los ofrece automáticamente ni define tokens de actualización.
ACL por tema: limite qué puede publicar o suscribir cada identidad. Expresiones como %u son sintaxis propia de algunos productos; verifique las reglas y pruebe accesos permitidos y denegados.
Para una aplicación de dispositivos médicos, TLS y permisos por tema pueden contribuir a una ruta de monitorización protegida si se configuran y verifican. No demuestran por sí solos cumplimiento normativo ni una tasa de intrusión nula. Valide payloads, identidades, actualizaciones, registros y requisitos aplicables al producto.
Mejores prácticas y auditoría
Use identidades de cliente diferenciadas, credenciales gestionadas y acceso anónimo desactivado cuando no sea necesario. Limite los permisos amplios de publicación y suscripción.
Mantenga activas la verificación de certificados y de host; registre CONNECT, desconexiones y rechazos útiles según el broker e integre los eventos con SIEM si corresponde. Evite registrar secretos o payloads sensibles.
Proteja la conexión al broker y póngala en marcha
Use TLS cuando el entorno lo admita y requiera, valide el certificado del broker, proteja credenciales y limite cada cliente a los temas necesarios. Separe permisos de publicación y suscripción: un publicador de telemetría no debe obtener permiso de órdenes por compartir conexión. La guía de software del router diferencia conectividad, firewall, aplicación y administración. MQTT no cifra la conexión por sí solo sin un transporte seguro configurado.
TLS, identidad, autorización por tema y failover requieren productos y configuración compatibles. El nombre de un protocolo o producto no demuestra que esos controles estén activos.
Configuración de un Broker MQTT y desarrollo del cliente
Proceso de configuración del Broker
Seleccione una versión y un modelo de despliegue adecuados; configure listeners, transporte, identidad, TLS y confianza antes de habilitar clientes.
Defina permisos por tema, política de sesión, retención, colas, tamaños y vencimientos según cada rol y la capacidad disponible.
Active puentes, plugins o monitorización solo si el producto los admite y la arquitectura los requiere. Pruebe límites, persistencia y recuperación en el broker elegido; no presuponga valores de ventana o cola.
Configurar el broker como servicio, no solo abrir un puerto
Documente listener y transporte, confianza de certificados, autenticación de clientes, ACL de publicación y suscripción por tema, límites de sesión y cola, persistencia y logs. MQTT claro y sobre TLS suelen usar puertos distintos, pero el listener concreto es decisión del despliegue. Limite alcance desde el sitio y evite escritura anónima en un broker público. Si se requiere alta disponibilidad, pruebe cómo el producto elegido conserva sesiones, suscripciones y mensajes retenidos tras failover; MQTT no garantiza clustering.
Empiece con un punto PLC conocido y un suscriptor. Verifique dirección del registro, unidad, marca de tiempo y carga útil; después publicación, suscripción y permisos. Desconecte WAN y reinicie cliente y broker en pruebas controladas. Compare lo recibido tras la recuperación y revise duplicados, datos retenidos antiguos, crecimiento de colas y consumo celular.
El control y las funciones de seguridad del PLC permanecen en su sistema aprobado salvo que un diseño revisado por separado autorice acciones mediante MQTT.
Poner en servicio con cuatro observaciones
Para un punto conocido capture lectura origen, intento de publicación, aceptación del broker y recepción del suscriptor con fechas. Después deniegue el permiso del tema y observe la respuesta; restáurelo e interrumpa WAN para investigar reconexión, duplicados y datos viejos. Guarde versiones de cliente y broker, modo TLS, tema, QoS y esquema del payload. Conectar por TCP solo demuestra alcance. La aceptación de aplicación exige un valor correcto, reciente y autorizado en el suscriptor.
Descripción general de los frameworks de desarrollo del cliente
Elija una biblioteca cliente por el lenguaje y la plataforma, las versiones MQTT, el soporte TLS, el modelo de eventos o callbacks, el ciclo de red y el mantenimiento. Eclipse Paho ofrece implementaciones diferentes por lenguaje; sus APIs y capacidades no son idénticas. Pools de conexión y publicación por lotes son decisiones de aplicación que deben medirse.
Desarrollo e integración de clientes MQTT
Integración con Java (Eclipse Paho)
El ejemplo usa Eclipse Paho Java 1.2.5 y MQTT 3.1.1. Es ilustrativo: configura TLS, opciones de Clean Session y comprobaciones limitadas de conexión y confirmación. No demuestra reconexión automática ni recuperación tras un corte; configure la confianza y la verificación del servidor para el broker que use.
// Eclipse Paho Java 1.2.5; MQTT 3.1.1; simulated telemetry.
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public final class MqttJavaExample {
static String required(String name) {
String value = System.getenv(name);
if (value == null || value.isEmpty()) throw new IllegalArgumentException(name);
return value;
}
public static void main(String[] args) throws Exception {
String broker = required("MQTT_BROKER_URI"); // ssl://dns-name:8883
if (!"ssl".equals(URI.create(broker).getScheme()))
throw new IllegalArgumentException("TLS broker URI required");
String topic = "demo/device01/telemetry";
CountDownLatch received = new CountDownLatch(1);
MqttClient client = new MqttClient(broker, required("MQTT_CLIENT_ID"),
new MemoryPersistence());
client.setTimeToWait(10000);
client.setCallback(new MqttCallback() {
public void connectionLost(Throwable error) {
System.err.println("Connection lost; stop and inspect recovery policy");
}
public void deliveryComplete(IMqttDeliveryToken token) { }
public void messageArrived(String name, MqttMessage message) {
if (!message.isRetained()) received.countDown();
}
});
MqttConnectOptions options = new MqttConnectOptions();
options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
options.setCleanSession(true); // This example does not resume offline state.
options.setAutomaticReconnect(false);
options.setConnectionTimeout(10);
options.setUserName(required("MQTT_USERNAME"));
options.setPassword(required("MQTT_PASSWORD").toCharArray());
options.setHttpsHostnameVerificationEnabled(true);
// Configure the JVM trust store with the broker's issuing CA.
try {
client.connect(options);
client.subscribe(topic, 1);
byte[] payload = "{\"example\":true,\"temperature\":23.5}".getBytes(StandardCharsets.UTF_8);
client.publish(topic, payload, 1, false);
if (!received.await(10, TimeUnit.SECONDS))
throw new IllegalStateException("No non-retained subscription delivery");
System.out.println("Demo MQTT exchange observed; no PLC action is implied");
} finally {
try { if (client.isConnected()) client.disconnect(); }
finally { client.close(); }
}
}
}
Interprete MqttException según la API y el protocolo usados. Los códigos de error de la biblioteca y los códigos de razón MQTT 5 no son intercambiables; 0x84 no significa de forma general «ID de cliente no válido». Registre el contexto del paquete y la respuesta real del broker sin incluir credenciales.
Integración con Go (Paho Go)
// github.com/eclipse/paho.mqtt.golang v1.5.0; MQTT 3.1.1.
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"net"
"os"
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
func required(name string) string {
value := os.Getenv(name)
if value == "" { panic("Missing " + name) }
return value
}
func checked(token mqtt.Token) {
if !token.WaitTimeout(10 * time.Second) { panic("MQTT operation timeout") }
if err := token.Error(); err != nil { panic(err) }
}
func main() {
host := required("MQTT_HOST") // DNS name covered by the broker certificate.
pem, err := os.ReadFile(required("MQTT_CA_FILE"))
if err != nil { panic(err) }
roots := x509.NewCertPool()
if !roots.AppendCertsFromPEM(pem) { panic("No CA certificate loaded") }
options := mqtt.NewClientOptions()
options.AddBroker("ssl://" + net.JoinHostPort(host, required("MQTT_PORT")))
options.SetClientID(required("MQTT_CLIENT_ID"))
options.SetUsername(required("MQTT_USERNAME"))
options.SetPassword(required("MQTT_PASSWORD"))
options.SetProtocolVersion(4) // MQTT 3.1.1.
options.SetCleanSession(true)
options.SetAutoReconnect(false)
options.SetConnectTimeout(10 * time.Second)
options.SetWriteTimeout(10 * time.Second)
options.SetTLSConfig(&tls.Config{
RootCAs: roots, ServerName: host, MinVersion: tls.VersionTLS12,
})
client := mqtt.NewClient(options)
checked(client.Connect())
defer client.Disconnect(1000)
topic := "demo/device01/telemetry"
received := make(chan struct{}, 1)
token := client.Subscribe(topic, 1, func(_ mqtt.Client, msg mqtt.Message) {
if !msg.Retained() {
select { case received <- struct{}{}: default: }
}
})
checked(token)
granted, ok := token.(*mqtt.SubscribeToken).Result()[topic]
if !ok || granted == 0x80 { panic("Subscription rejected") }
checked(client.Publish(topic, 1, false, `{"example":true,"temperature":23.5}`))
select {
case <-received:
fmt.Println("Demo MQTT exchange observed; no PLC action is implied")
case <-time.After(10 * time.Second):
panic("No non-retained subscription delivery")
}
}
Las goroutines permiten organizar trabajo concurrente en Go, pero no garantizan una capacidad determinada. Mantenga breves los callbacks de la biblioteca y pase el procesamiento costoso a una cola acotada; gestione errores y presión de carga en la aplicación.
Integración con Python (Paho MQTT)
# paho-mqtt 2.1.0; Callback API VERSION2; MQTT 3.1.1.
import os
import ssl
import threading
import paho.mqtt.client as mqtt
connected = threading.Event()
subscribed = threading.Event()
received = threading.Event()
errors = []
topic = "demo/device01/telemetry"
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
errors.append("Broker rejected CONNECT")
connected.set()
def on_subscribe(client, userdata, mid, reason_codes, properties):
if not reason_codes or any(code.is_failure for code in reason_codes):
errors.append("Broker rejected SUBSCRIBE")
subscribed.set()
def on_message(client, userdata, message):
if not message.retain:
received.set()
def ready(event):
if not event.wait(10):
raise TimeoutError("MQTT readiness timeout")
if errors:
raise RuntimeError(errors[0])
client = mqtt.Client(
callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
client_id=os.environ["MQTT_CLIENT_ID"],
clean_session=True, protocol=mqtt.MQTTv311, reconnect_on_failure=False,
)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_message = on_message
context = ssl.create_default_context(cafile=os.environ["MQTT_CA_FILE"])
context.minimum_version = ssl.TLSVersion.TLSv1_2
client.tls_set_context(context) # Certificate and hostname verification stay enabled.
client.username_pw_set(os.environ["MQTT_USERNAME"], os.environ["MQTT_PASSWORD"])
client.connect(os.environ["MQTT_HOST"], int(os.environ["MQTT_PORT"]), keepalive=30)
client.loop_start()
try:
ready(connected)
result, _ = client.subscribe(topic, qos=1)
if result != mqtt.MQTT_ERR_SUCCESS:
raise RuntimeError("Unable to queue SUBSCRIBE")
ready(subscribed)
info = client.publish(topic, '{"example":true,"temperature":23.5}', qos=1, retain=False)
if info.rc != mqtt.MQTT_ERR_SUCCESS:
raise RuntimeError("Unable to queue PUBLISH")
info.wait_for_publish(timeout=10)
if not info.is_published():
raise TimeoutError("Publication was not acknowledged")
ready(received)
print("Demo MQTT exchange observed; no PLC action is implied")
finally:
client.disconnect()
client.loop_stop()
Si la aplicación usa asyncio, integre el ciclo de red de Paho mediante el mecanismo de integración externa que documente la versión elegida. Evite llamadas bloqueantes o esperas largas dentro de un callback.
Criterios para comparar bibliotecas cliente
Lenguaje | Consideraciones sobre la biblioteca y el entorno | Comportamiento de conexión que medir | Modelo de concurrencia o eventos | Preguntas de integración |
|---|---|---|---|---|
Java | El paquete Paho, la JVM y los buffers TLS afectan al entorno; el consumo depende del paquete y la plataforma. | Mida DNS, TCP, TLS, autenticación y respuesta del broker por separado. | API síncrona o asíncrona y callbacks según el cliente elegido. | Aplicaciones JVM empresariales: compatibilidad con el runtime, la seguridad y el ciclo de vida. |
Go | Considere el módulo, el runtime y las dependencias de transporte. | Mida handshake, callbacks, confirmaciones y presión de cola bajo el workload real. | Goroutines y callbacks; acote el trabajo concurrente y las colas. | Servicios concurrentes: revise cancelación, backpressure, cierre y reconexión. |
Python | Considere paho-mqtt, el entorno virtual, TLS y dependencias del sistema. | Mida el ciclo de red elegido, TLS, callbacks y comportamiento ante cortes. | Callbacks y loop de red; la integración con asyncio debe ajustarse a la API. | Scripts o procesamiento de datos: valide el modelo de eventos y la versión de callbacks. |
Comparativa de seguridad y rendimiento: MQTT vs otros protocolos
La selección depende del modelo de interacción, la implementación, el payload, la red y los requisitos de seguridad. La tabla mantiene las dimensiones de modo, overhead, seguridad, rendimiento y uso, pero no asigna benchmarks universales; mida las versiones y configuraciones concretas.
Protocolo | Modelo de interacción | Overhead (bytes por mensaje) | Seguridad (cifrado/autenticación) | Rendimiento (caudal/latencia) | Usos y compromisos |
|---|---|---|---|---|---|
MQTT | Publicación/suscripción mediada por broker. | Depende de la versión, el tipo de paquete, tema, propiedades y payload; mida una captura representativa. | TLS con verificación de pares y autenticación/ACL del broker según configuración; JWT no es universal. | Mida cliente, broker, red, payload, QoS y persistencia del despliegue. | Telemetría y eventos; depende de broker y contrato de temas. |
CoAP | Solicitud/respuesta sobre datagramas; puede incluir observación. | Depende de opciones, token, payload, seguridad y segmentación. | DTLS u otros mecanismos compatibles; la identidad y permisos dependen del despliegue. | Mida pérdidas, retransmisiones, seguridad y transporte usados. | Recursos con restricciones y patrón de solicitud; examine descubrimiento y alcance de la infraestructura. |
AMQP 1.0 | Mensajería con sesiones, enlaces y transferencias; no confundir con modelos de exchange propios de productos. | Depende del framing, propiedades, payload y transporte. | TLS y SASL son opciones de transporte/autenticación según endpoints; permisos dependen del producto. | Mida framing, persistencia, confirmaciones, broker y carga. | Integración de mensajería; ofrece otro modelo de enlaces y asentamiento, con mayor configuración. |
XMPP | Flujos XML con stanzas y extensiones. | La serialización, extensiones y payload determinan los bytes transmitidos. | TLS y SASL están definidos para flujos XMPP; la política de identidad y autorización depende del servicio. | Mida serialización, extensiones, conexiones y carga. | Mensajería, presencia o extensiones de IoT; el XML puede requerir más volumen que un payload compacto. |
DDS | Publicación/suscripción centrada en datos, a menudo distribuida. | Depende del middleware, descubrimiento, transporte y perfil de seguridad. | Evalúe perfiles DDS Security y configuración admitida; no presuponga un mecanismo común. | Mida descubrimiento, QoS, middleware, transporte y topología. | Sistemas de datos distribuidos con requisitos de tiempo; la interoperabilidad y configuración dependen de perfiles. |
Elija por el patrón de interacción y el ciclo de vida requeridos. MQTT puede distribuir eventos mediante un broker; CoAP puede servir recursos en redes restringidas; AMQP 1.0 ofrece otro modelo de transferencia de mensajes. Una arquitectura híbrida con broker perimetral y servicio de mensajería central es una opción de diseño, no un resultado garantizado.
Arquitectura de la pila de protocolos MQTT industrial
Las capas siguientes ilustran una posible implementación industrial; MQTT no exige esta arquitectura ni garantiza tiempo real o interoperabilidad. Separar adquisición, mapeo, broker y gestión ayuda a asignar responsabilidades y verificar cada tramo.
Capa EMS (Subsistema de Gestión de Dispositivos)
Un servicio de gestión de equipos podría usar eventos de conexión, frescura de datos, configuración y ciclo de vida del dispositivo. LWT es una señal de conexión, no estado de máquina. Las actualizaciones OTA y herramientas como Eclipse Hono requieren una integración y compatibilidad propias.
Capa de controladores de pasarela (Gateway)
Una pasarela puede leer una interfaz de campo compatible, aplicar tipos, escalas y marcas temporales documentados, normalizar temas y publicar un payload acordado. La integración Modbus a MQTT y el puente OPC UA Pub/Sub requieren controladores y configuración; el buffer y sus límites dependen del producto y la carga.
Capa de controladores de bajo nivel
La plataforma aporta controladores de dispositivo y red y, cuando se requiere, transporte TLS con verificación de pares. La biblioteca MQTT gestiona sus paquetes y el estado QoS que admita; buffers, pila TCP/TLS y consumo dependen del hardware, compilación y tráfico. lwIP es una opción, no un requisito ni una garantía de consumo.
Un ejemplo de arquitectura de fabricación podría conectar un sensor o PLC Modbus con un colector documentado, una pasarela que mapea datos, un broker y una aplicación de gestión. Asigne a cada tramo adquisición, normalización, permisos y auditoría; verifique la persistencia y el failover del producto elegido. No se atribuye una reducción de inactividad ni una función de network slicing a MQTT.
Desarrollo de clientes MQTT industriales
Integración con C++ (Paho C++)
// Paho C++ 1.5.3 with a TLS-enabled Paho C dependency; MQTT 3.1.1.
#include <mqtt/async_client.h>
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <string>
std::string required(const char* name) {
const char* value = std::getenv(name);
if (!value || !*value) throw std::runtime_error(name);
return value;
}
void checked(mqtt::token_ptr token) {
if (!token->wait_for(std::chrono::seconds(10)))
throw std::runtime_error("MQTT operation timeout");
}
int main() {
try {
const auto uri = required("MQTT_BROKER_URI"); // ssl://dns-name:8883
if (uri.rfind("ssl://", 0) != 0) throw std::runtime_error("TLS URI required");
mqtt::async_client client(uri, required("MQTT_CLIENT_ID"));
mqtt::ssl_options tls;
tls.set_trust_store(required("MQTT_CA_FILE"));
tls.set_enable_server_cert_auth(true);
tls.set_verify(true); // Check the broker certificate host name.
mqtt::connect_options options;
options.set_mqtt_version(MQTTVERSION_3_1_1);
options.set_clean_session(true);
options.set_connect_timeout(10);
options.set_user_name(required("MQTT_USERNAME"));
options.set_password(required("MQTT_PASSWORD"));
options.set_ssl(tls);
client.start_consuming();
try {
checked(client.connect(options));
checked(client.subscribe("demo/device01/telemetry", 1));
auto message = mqtt::make_message("demo/device01/telemetry",
"{\"example\":true,\"temperature\":23.5}");
message->set_qos(1);
message->set_retained(false);
checked(client.publish(message));
mqtt::const_message_ptr incoming;
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10);
while (std::chrono::steady_clock::now() < deadline) {
incoming = client.try_consume_message_for(std::chrono::milliseconds(200));
if (incoming && !incoming->is_retained()) break;
}
if (!incoming || incoming->is_retained())
throw std::runtime_error("No non-retained subscription delivery");
checked(client.disconnect());
client.stop_consuming();
} catch (...) {
client.stop_consuming();
if (client.is_connected()) { try { client.disconnect()->wait_for(std::chrono::seconds(2)); } catch (...) {} }
throw;
}
std::cout << "Demo MQTT exchange observed; no PLC action is implied\n";
} catch (const std::exception& error) {
std::cerr << error.what() << '\n';
return 1;
}
}
Técnicas como zero-copy y análisis JSON con SIMD pueden considerarse si la biblioteca, el hardware y el perfil de carga las permiten. Mida antes de optimizar; no se atribuyen esas capacidades a todos los clientes C++.
Variante Java embebida (Android/IoT)
En Android u otra plataforma Java gestionada, adapte el cliente al ciclo de vida y a las restricciones de red del sistema. WorkManager programa trabajo diferible; no garantiza una conexión MQTT continua ni una reconexión en tiempo real. Seleccione el mecanismo de ejecución en segundo plano permitido para la tarea y compruebe sus límites.
C embebido (ESP32/FreeRTOS)
/* Paho paho.mqtt.embedded-c MQTTClient-C API, single-task platform fragment.
* Build with the library's platform header (Network and Timer definitions).
* tls_network must ALREADY be connected through a platform TLS adapter that
* validates the CA chain and broker host name. Plain TCP is not sufficient.
* Caller owns that transport and its cleanup. Payload is simulated telemetry.
*/
#include "MQTTClient.h"
#include <string.h>
#include <stdio.h>
static void arrived(MessageData* data) {
MQTTMessage* message = data->message;
printf("Received %u payload bytes\n", (unsigned)message->payloadlen);
}
int publish_demo(Network* tls_network, const char* client_id,
const char* username, const char* password) {
if (!tls_network || !client_id || !*client_id || !username || !password)
return -1;
unsigned char send_buffer[512], read_buffer[512];
MQTTClient client;
MQTTClientInit(&client, tls_network, 5000,
send_buffer, sizeof send_buffer, read_buffer, sizeof read_buffer);
MQTTPacket_connectData options = MQTTPacket_connectData_initializer;
options.MQTTVersion = 4; /* MQTT 3.1.1 */
options.clientID.cstring = (char*)client_id;
options.username.cstring = (char*)username;
options.password.cstring = (char*)password;
options.cleansession = 1;
options.keepAliveInterval = 30;
int rc = MQTTConnect(&client, &options);
if (rc != 0) return rc;
rc = MQTTSubscribe(&client, "demo/device01/telemetry", QOS1, arrived);
if (rc == 0) {
char payload[] = "{\"example\":true,\"temperature\":23.5}";
MQTTMessage message = {0};
message.qos = QOS1;
message.retained = 0;
message.payload = payload;
message.payloadlen = strlen(payload);
rc = MQTTPublish(&client, "demo/device01/telemetry", &message);
if (rc == 0) rc = MQTTYield(&client, 1000);
}
int close_rc = MQTTDisconnect(&client);
return rc != 0 ? rc : close_rc;
}
En un objetivo embebido, buffers estáticos y una asignación dinámica acotada pueden ayudar a planificar memoria. lwIP y TLS dependen del port, el hardware y la integración elegidos; verifique el tamaño de pila, los buffers, la validación de certificados y los límites de cola.
Valide límites de buffers y payload, códigos de retorno, pérdida de conexión, credenciales vencidas y cierre de la aplicación en el dispositivo objetivo. Pruebe patrones de interrupción relevantes para la instalación y revise el uso de memoria con las herramientas disponibles para la plataforma; no fije porcentajes de cobertura ni de pérdida arbitrarios.
Resumen
Evaluación de ventajas y desventajas
Ventajas:
Distribución desacoplada: la publicación por temas permite que varios consumidores autorizados reciban eventos sin mantener conexiones directas entre aplicaciones.
Controles de entrega y ciclo de vida: QoS, sesiones y Will ofrecen mecanismos de protocolo cuya utilidad depende de las necesidades, configuración y soporte.
Ecosistema de clientes y brokers: existen implementaciones para distintas plataformas; compare mantenimiento, APIs, seguridad y compatibilidad de versiones.
Limitaciones:
Dependencia del broker: capacidad, almacenamiento, disponibilidad y recuperación requieren un diseño y una validación específicos.
Descubrimiento e integración: MQTT no define un servicio universal de descubrimiento ni lee o mapea por sí mismo registros PLC.
Coste de QoS 2: usa un intercambio de protocolo con más estado que QoS 0 o 1; no hay un múltiplo fijo de RTT ni un límite universal para tiempo real.
Ampliación de escenarios de aplicación
IoT: telemetría de hogares inteligentes y eventos de vehículos conectados; defina frescura, identidad y permisos.
IIoT: monitorización de equipos e integración de datos de PLC con una pasarela y una lógica de control documentadas; MQTT no sustituye automáticamente la red de control.
Edge/nube: un broker perimetral puede reenviar datos hacia servicios centrales si la arquitectura y el producto lo admiten; mida latencia y comportamiento durante cortes.
Para flujos grandes de datos, requisitos estrictos de tiempo o transacciones síncronas, evalúe otra arquitectura o un servicio adicional. Herramientas de streaming o RPC pueden encajar en ciertos casos, pero la elección debe partir del volumen, la latencia, la entrega y el modelo de operación reales.
Principios de diseño de temas (guía avanzada)
Defina una jerarquía estable por función, región, sitio, equipo y métrica; por ejemplo, separe cmd/ de telemetry/ y documente qué rol puede publicar o suscribirse a cada nivel.
Mantenga nombres legibles dentro de los límites codificados del protocolo y del producto; no imponga un máximo genérico de caracteres. En MQTT 5, Topic Alias es un mapeo negociado, limitado a una conexión y dirección, no un reemplazo permanente del contrato de temas.
Aplique mínimo privilegio a filtros y ACL. Una suscripción amplia con # no debe otorgar permiso para publicar comandos; restrinja y pruebe por separado lectura, telemetría y control.
Versione deliberadamente el esquema y el espacio de nombres, por ejemplo v1/telemetry/..., y documente unidades, identidad y compatibilidad para consumidores existentes.
Mida coincidencia y distribución en el broker elegido. Una jerarquía de prefijos ordenada no determina el algoritmo ni garantiza rendimiento.
FAQ
¿Qué es MQTT y sigue usándose en sistemas industriales?
MQTT es un estándar de mensajería cliente-servidor basado en publicación/suscripción, usado en intercambios de datos de equipos conectados e industriales. Los clientes publican en temas y reciben suscripciones autorizadas coincidentes mediante un broker. Que MQTT y una implementación mantenida sean adecuados depende de la ruta de datos, los recursos, la seguridad y el ciclo de vida del sistema, no de una afirmación de adopción universal.
¿Sustituye MQTT a Modbus en la red de la máquina?
No. Una pasarela puede leer datos Modbus y publicar una carga MQTT mapeada, pero los protocolos cumplen funciones distintas. Confirme el mapa de registros y la conversión.
¿Garantiza QoS 2 que una acción de la máquina ocurra una sola vez?
No. QoS 2 cubre el intercambio MQTT, no el controlador ni la operación posterior. Identifique las órdenes y verifique el resultado de aplicación en un diseño de control aprobado.
¿Un mensaje retenido siempre es el valor actual?
No. Es la última publicación retenida de ese tema en el broker. Compruebe tiempo, calidad y política de caducidad.
¿Funciona MQTT por red celular con direcciones IP cambiantes?
A menudo un cliente puede iniciar una conexión saliente a un broker accesible, según operador, firewall y configuración. Pruebe reconexión y colas; MQTT no convierte por sí solo una conexión débil en fiable.
¿Puede el publicador usar un tema con comodín?
No. Los comodines son para filtros de suscripción. El publicador usa un tema concreto que el broker compara con filtros permitidos.
¿PUBACK prueba que el panel procesó el valor?
No. Confirma un paso MQTT QoS 1, no la decisión de la aplicación suscriptora. Verifique por separado aceptación del broker, recepción y resultado mostrado o guardado.
¿Qué biblioteca cliente MQTT conviene para Java, Go, Python o un equipo embebido?
Compare una biblioteca mantenida para el lenguaje y la plataforma con la versión MQTT requerida, TLS con verificación de confianza y host, modelo de callbacks o ciclo de red y comportamiento de sesión y recuperación. Los ejemplos de esta guía usan Eclipse Paho Java 1.2.5, Paho Go v1.5.0, paho-mqtt 2.1.0 con Callback API V2, Paho C++ 1.5.3 y la API MQTTClient-C para C embebido. Son límites de los ejemplos, no una recomendación única ni un diseño de recuperación de producción.
Referencias
OASIS MQTT Version 5.0 — Reglas de MQTT 5.0 sobre QoS, sesiones, publicaciones retenidas, Will y propiedades de versión.
OASIS MQTT Version 3.1.1 — Estándar MQTT 3.1.1 y comportamiento de conexión, sesión y entrega.
Eclipse Mosquitto Configuration Manual — Opciones de Mosquitto para listeners, autenticación, autorización, TLS, persistencia y operación del broker.
Eclipse Paho — Catálogo oficial de implementaciones cliente de Eclipse Paho y documentación de sus componentes.
Eclipse Paho Python Migration Guide — Cambios entre versiones de Paho Python y uso de callbacks versionados, incluida Callback API V2.
RFC 7252 — CoAP — Especificación base de CoAP para recursos restringidos, solicitudes y datagramas.
OASIS AMQP 1.0 Overview — Especificación OASIS AMQP 1.0 sobre transporte, mensajería, transferencias y seguridad; distíngala de modelos propios de productos.
RFC 6120 — XMPP Core — Especificación central de XMPP sobre flujos XML, autenticación y protección del canal.
OMG DDS 1.4 Specification — Especificación oficial DDS 1.4 de publicación/suscripción centrada en datos y contexto de perfiles/QoS.



