Un explorador de topics MQTT muestra todos los topics que pasan por un broker como un árbol desplegable en vivo, con el último payload junto a cada nodo. En este tutorial generarás una jerarquía de topics realista, la explorarás en el explorador de topics en vivo de ConnectMQ y en la línea de comandos, y aprenderás los patrones que revelan en segundos errores de nombres, retained messages obsoletos y payloads mal formados.
Qué hace un explorador de topics MQTT
MQTT no tiene un comando integrado para "listar topics". Los topics no se crean ni se registran; existen solo porque alguien publica en ellos. Un explorador de topics sortea esto suscribiéndose a un comodín amplio como # (o a la raíz de un proyecto como factory1/#) y construyendo un árbol a partir de las cadenas de topic que recibe. Cada barra se convierte en un nivel, cada nivel en una carpeta, y el payload más reciente se muestra en la hoja.
Esa idea sencilla es sorprendentemente potente. Un flujo plano de mensajes de mosquitto_sub es difícil de leer en cuanto tienes más de una docena de dispositivos. Un árbol te dice de un vistazo:
- Qué ramas existen y cuáles no deberían existir.
- Qué hojas se están actualizando ahora mismo y cuáles se detuvieron hace horas.
- Qué valores están retenidos, es decir, cuáles recibirá inmediatamente un nuevo suscriptor.
- Qué tamaño tienen los payloads y lo bien formados que están.
Si la estructura de topics es nueva para ti, conviene entender qué hace un broker MQTT con los topics y las suscripciones antes de empezar.
Genera un árbol de topics para explorar
Necesitas tráfico para explorar. El script siguiente publica una pequeña jerarquía de fábrica en el servidor MQTT público gratuito de broker.connectmq.com, pensado para pruebas y prototipos, no para datos de producción. Incluye a propósito tres errores habituales para que puedas encontrarlos en el explorador. Instala el cliente con pip install "paho-mqtt>=2.0".
import json
import random
import time
import uuid
import paho.mqtt.client as mqtt
RUN_ID = uuid.uuid4().hex[:6]
ROOT = f"connectmq/demo/{RUN_ID}"
client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id=f"tree-gen-{RUN_ID}",
)
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
print(f"Publishing under {ROOT}/ (subscribe to {ROOT}/#)")
# Metadatos de dispositivo retenidos
for line in ("line1", "line2"):
for machine in ("cnc1", "cnc2"):
meta = {"vendor": "demo", "model": "X200", "line": line}
client.publish(f"{ROOT}/factory1/{line}/{machine}/meta",
json.dumps(meta), qos=1, retain=True)
# Error 1: mayúsculas incoherentes crean una rama paralela
client.publish(f"{ROOT}/factory1/Line1/cnc1/meta", "{}", qos=1, retain=True)
# Error 2: una barra final crea un último nivel vacío
client.publish(f"{ROOT}/factory1/line2/cnc2/telemetry/", "42", qos=0)
try:
while True:
for line in ("line1", "line2"):
for machine in ("cnc1", "cnc2"):
payload = {
"spindle_rpm": random.randint(9000, 12000),
"temperature": round(random.uniform(35, 60), 1),
"ts": int(time.time()),
}
client.publish(f"{ROOT}/factory1/{line}/{machine}/telemetry",
json.dumps(payload), qos=0)
# Error 3: un payload que no es JSON válido
client.publish(f"{ROOT}/factory1/line1/cnc2/telemetry",
"temp=48.2;rpm=10100", qos=0)
time.sleep(2)
except KeyboardInterrupt:
client.loop_stop()
client.disconnect()
El script publica cuatro mensajes por ciclo más el mal formado, lo que lo mantiene holgadamente por debajo del límite del broker público de 10 mensajes por segundo por cliente. Déjalo en ejecución y anota la raíz que imprime.
Explora el árbol en el explorador de topics de ConnectMQ
En tu propio broker, el explorador de topics en vivo del portal de ConnectMQ es el explorador de topics integrado. Para seguir los pasos, crea un broker gratuito en el portal y apunta a él el script anterior cambiando al puerto 8883 con TLS y añadiendo las credenciales que generó el portal (YOUR_USERNAME, YOUR_PASSWORD, YOUR_CLIENT_ID). Si prefieres echar un vistazo rápido al broker público, cualquier explorador MQTT que admita WebSockets puede conectarse a wss://broker.connectmq.com:8084/mqtt y suscribirse a tu raíz connectmq/demo/<run-id>/#.
A medida que llegan los mensajes, recorre el árbol desde arriba:
- Despliega la raíz. Deberías ver
factory1y, debajo,line1,line2y un inesperadoLine1. Los topics distinguen mayúsculas y minúsculas, así queLine1es una rama aparte que ningún suscriptor deline1/#recibirá jamás. - Abre
line2/cnc2. Bajotelemetryhay un hijo con el nombre vacío. Es la barra final:telemetry/tiene un nivel más quetelemetry, y una suscripción a.../cnc2/telemetryno coincidirá con él. - Abre
line1/cnc2/telemetry. El valor alterna entre JSON ytemp=48.2;rpm=10100. Cualquier consumidor que interprete JSON fallará con uno de cada dos mensajes. - Mira las hojas
meta. Llevan el flag de retenido. Desconéctate y vuelve a conectarte: aparecen al instante, mientras que la telemetría solo se muestra cuando llega el siguiente mensaje.
El portal de ConnectMQ también ofrece una vista de dispositivos organizada por niveles ISA-95 (empresa, sitio, área, línea, celda). Si tus topics siguen una estructura de Unified Namespace, esa vista agrupa los mismos datos por la jerarquía de la planta en lugar de por cadenas en bruto, lo que hace que los dispositivos mal ubicados salten a la vista. Nuestro artículo sobre Sparkplug B y el Unified Namespace explica esa estructura.
Explora topics desde la línea de comandos
No siempre tienes a mano un explorador gráfico. mosquitto_sub con el flag -v imprime el topic antes de cada payload, y unos pocos flags más lo convierten en un explorador ligero:
# Todos los topics bajo tu raíz, con sus nombres
mosquitto_sub -h broker.connectmq.com -p 1883 -i browse-$RANDOM \
-t 'connectmq/demo/RUN_ID/#' -v
# Solo retained messages: conecta, imprime lo retenido y sale a los 3 s
mosquitto_sub -h broker.connectmq.com -p 1883 -i retained-$RANDOM \
-t 'connectmq/demo/RUN_ID/#' -v --retained-only -W 3
# Nombres de topic únicos vistos en 30 segundos
timeout 30 mosquitto_sub -h broker.connectmq.com -p 1883 -i list-$RANDOM \
-t 'connectmq/demo/RUN_ID/#' -F '%t' | sort -u
Sustituye RUN_ID por el valor que imprimió el script. El último comando es lo más parecido que tiene MQTT a "listar topics", y es una forma rápida de comparar los topics que esperas con los que existen realmente. Encontrarás más recetas en nuestros ejemplos de mosquitto_pub y mosquitto_sub.
Patrones de depuración que revela un explorador de topics
Cuando te acostumbras a leer un árbol, la mayoría de los problemas de topics encajan en un número reducido de patrones.
| Lo que ves en el árbol | Qué significa | Solución |
|---|---|---|
| Dos ramas que solo se diferencian en mayúsculas | Nomenclatura incoherente en el firmware o la configuración | Estandariza en minúsculas y hazlo cumplir en la revisión de código |
| Una hoja con el nombre vacío | Barra final en el topic de publicación | Elimina las barras finales antes de publicar |
| Un primer nivel con el nombre vacío | Barra inicial (/factory1/...) |
Quita la barra inicial; añade un nivel inútil |
| Una hoja cuyo valor nunca cambia | El dispositivo dejó de publicar o el valor es un retenido obsoleto | Revisa el dispositivo; borra el retained message si está obsoleto |
| Valores que alternan entre formatos | Dos versiones de firmware o dos publicadores en un mismo topic | Versiona el payload o separa los topics |
| Cientos de hojas hermanas con IDs en el nombre | IDs únicos colocados demasiado arriba en la jerarquía | Baja los IDs al nivel de dispositivo |
| Ramas muy profundas | Topics sobreestructurados | Aplana; el broker público permite 8 niveles |
Borrar retained messages obsoletos
Los valores retenidos persisten en el broker hasta que se reemplazan. Por eso, un dispositivo dado de baja puede seguir mostrando un valor "actual" en todos los paneles. Para eliminar un retained message, publica un payload retenido vacío en el topic exacto:
mosquitto_pub -h broker.connectmq.com -p 1883 -i clear-$RANDOM \
-t 'connectmq/demo/RUN_ID/factory1/Line1/cnc1/meta' -r -n
El flag -n envía un payload de longitud cero y -r activa el flag retain. Actualiza el explorador de topics y la rama Line1 desaparecerá en cuanto no tenga otros hijos.
Usar bien un explorador de topics en producción
Un explorador que se suscribe a # en un broker de producción con mucho tráfico recibe todos los mensajes, lo que consume ancho de banda y puede alcanzar las cuotas de suscripciones o conexiones. Algunos hábitos lo mantienen útil:
- Suscríbete a la raíz más estrecha que responda a tu pregunta, como
factory1/line2/#, en lugar de#. - Usa una credencial dedicada para las herramientas de depuración, para que una sesión del explorador nunca tome el client ID de un dispositivo y lo deje desconectado.
- Comprueba el estado de conexión además de los datos. El topic
$SYS/broker/connection/{clientId}/statede tu broker de ConnectMQ te dice si un cliente concreto está conectado, lo que distingue "dispositivo desconectado" de "dispositivo conectado pero en silencio". - Pon por escrito tus reglas de nomenclatura y compara el árbol con ellas tras cada versión de firmware.
Para flujos de trabajo centrados en el editor, la extensión de ConnectMQ para VS Code y el explorador MQTT de escritorio de ConnectMQ ofrecen la misma exploración en árbol fuera del portal. Si solo pruebas desde un navegador, nuestra guía para usar un cliente web MQTT online complementa bien a esta, y monitorización de un broker MQTT cubre las métricas que un explorador de topics no muestra.
Explora tus propios topics en ConnectMQ
Crea un broker gratuito en app.connectmq.com con el plan Serverless, sin tarjeta de crédito. El portal incluye el explorador de topics en vivo, el cliente en el navegador y la vista de dispositivos ISA-95 usados en esta guía. Descubre más sobre ConnectMQ como broker MQTT gestionado o lee la guía general para elegir un broker MQTT en la nube.
Preguntas frecuentes
¿Puedo listar todos los topics de un broker MQTT?
No directamente; MQTT no tiene un registro de topics. Un explorador de topics se suscribe a un comodín y muestra los topics que reciben mensajes, además de los topics retenidos, que es el equivalente práctico.
¿Por qué mi explorador de topics no muestra un topic que sé que existe?
O no se ha publicado nada en él desde que te suscribiste y no contiene ningún retained message, o tu comodín no lo cubre. Revisa las mayúsculas, las barras iniciales o finales y la raíz de la suscripción.
¿Es seguro suscribirse a # en un broker de producción?
Funciona, pero recibe todos los mensajes, lo que puede ser pesado. Suscríbete a la raíz más estrecha que responda a tu pregunta y usa una credencial de depuración dedicada.
¿Cómo elimino un topic del árbol?
Los topics desaparecen cuando nada los mantiene. Borra un retained message publicando un payload retenido vacío en ese topic exacto y detén el publicador que lo crea.



