Sacar un cliente de HiveMQ Cloud Serverless cambia cuatro cosas: el hostname, las credenciales, el client ID y, a veces, los ajustes de confianza de TLS. Tus topics, tus payloads y la lógica de tu aplicación siguen igual. Este artículo muestra exactamente qué cambiar en los clientes más habituales, con ejemplos de antes y después usando como destino un broker privado de ConnectMQ.
El proceso general está en la guía de migración de HiveMQ Serverless.
Qué cambia y qué se mantiene
| Ajuste | HiveMQ Cloud Serverless | ConnectMQ |
|---|---|---|
| Hostname | <cluster-id>.s1.eu.hivemq.cloud |
broker.connectmq.com |
| MQTT sobre TLS | 8883 | 8883 |
| WebSocket seguro | 8884, ruta /mqtt |
8084, ruta /mqtt |
| Usuario y contraseña | Creados en la consola de HiveMQ | Generados por broker en el portal de ConnectMQ |
| Client ID | Elegido libremente | El client ID emitido, opcionalmente con un _sufijo |
| Certificado raíz | De confianza pública | Let's Encrypt (ISRG Root X1), de confianza pública |
| Topics, payloads, QoS | Sin cambios | Sin cambios |
Fíjate en el puerto de WebSocket seguro: los dashboards de navegador suelen tener 8884 escrito en el código, mientras que ConnectMQ usa 8084. Revisa en la consola de HiveMQ los valores exactos que usaba tu clúster.
ESP32 con Arduino y PubSubClient
Antes (HiveMQ Cloud):
const char* MQTT_HOST = "abc123.s1.eu.hivemq.cloud";
const char* MQTT_USER = "hivemq-user";
const char* MQTT_PASS = "hivemq-pass";
String clientId = "sensor-" + WiFi.macAddress();
Después (ConnectMQ):
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
const char* MQTT_HOST = "broker.connectmq.com";
const int MQTT_PORT = 8883;
const char* MQTT_USER = "YOUR_USERNAME";
const char* MQTT_PASS = "YOUR_PASSWORD";
const char* CLIENT_ID_BASE = "YOUR_CLIENT_ID";
// ISRG Root X1 (Let's Encrypt): pega el PEM de letsencrypt.org/certificates
static const char ROOT_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
...ISRG Root X1...
-----END CERTIFICATE-----
)EOF";
WiFiClientSecure net;
PubSubClient mqtt(net);
void connectMqtt() {
String mac = WiFi.macAddress();
mac.replace(":", "");
String clientId = String(CLIENT_ID_BASE) + "_" + mac; // ID emitido + sufijo único
while (!mqtt.connected()) {
if (mqtt.connect(clientId.c_str(), MQTT_USER, MQTT_PASS)) {
mqtt.publish("site1/esp32/status", "online", true); // vuelve a publicar el estado retenido
mqtt.subscribe("site1/esp32/cmd");
} else {
delay(5000);
}
}
}
void setup() {
// ... conecta primero el Wi-Fi ...
net.setCACert(ROOT_CA);
mqtt.setServer(MQTT_HOST, MQTT_PORT);
mqtt.setBufferSize(1024);
connectMqtt();
}
void loop() {
if (!mqtt.connected()) connectMqtt();
mqtt.loop();
}
Si tu firmware para HiveMQ usaba setInsecure(), aprovecha para verificar los certificados correctamente. Tienes más detalles en ESP32 MQTT con SSL. Recuerda que el ESP32 necesita la hora correcta para algunas pilas TLS; sincroniza NTP antes de conectarte.
Python con paho-mqtt 2.x
Antes:
client.username_pw_set("hivemq-user", "hivemq-pass")
client.connect("abc123.s1.eu.hivemq.cloud", 8883)
Después:
# pip install "paho-mqtt>=2.0"
import os, ssl
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client.subscribe("site1/#", qos=1)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=os.environ["MQTT_CLIENT_ID"] + "_ingest",
protocol=mqtt.MQTTv5)
client.username_pw_set(os.environ["MQTT_USERNAME"], os.environ["MQTT_PASSWORD"])
client.tls_set(cert_reqs=ssl.CERT_REQUIRED) # el almacén de CA del sistema confía en Let's Encrypt
client.on_connect = on_connect
client.on_message = lambda c, u, m: print(m.topic, m.payload.decode())
client.connect("broker.connectmq.com", 8883)
client.loop_forever()
Suscribirse en on_connect es importante: restaura las suscripciones tras cada reconexión, de modo que el cliente nunca depende del estado de sesión almacenado en un broker. Consulta paho-mqtt en Python y reconexión con paho-mqtt.
Node.js con MQTT.js
// npm install mqtt
const mqtt = require("mqtt");
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
// antes: mqtts://abc123.s1.eu.hivemq.cloud:8883
username: process.env.MQTT_USERNAME,
password: process.env.MQTT_PASSWORD,
clientId: `${process.env.MQTT_CLIENT_ID}_api`,
protocolVersion: 5,
reconnectPeriod: 2000,
});
client.on("connect", () => client.subscribe("site1/+/telemetry", { qos: 1 }));
client.on("message", (topic, payload) => console.log(topic, payload.toString()));
client.on("error", (err) => console.error("MQTT error:", err.message));
Para un dashboard en el navegador, usa wss://broker.connectmq.com:8084/mqtt con las mismas opciones. Consulta MQTT.js con Node.js y MQTT sobre WebSocket.
Node-RED
En Node-RED, todos los nodos MQTT comparten un único nodo de configuración del broker, así que la migración suele ser una sola edición:
- Abre cualquier nodo mqtt in o mqtt out y haz clic en el lápiz junto al servidor.
- Pestaña Connection: pon Server en
broker.connectmq.com, Port en8883, marca Use TLS y selecciona una configuración TLS que verifique el certificado del servidor. Pon Protocol en MQTT V5 si usas funciones de MQTT 5. - Client ID: introduce tu client ID emitido con un sufijo, por ejemplo
YOUR_CLIENT_ID_nodered. - Pestaña Security: introduce el nuevo usuario y la nueva contraseña.
- Haz Deploy y comprueba que los nodos muestran connected.
Si el nodo sigue mostrando "connecting", consulta Node-RED MQTT no conecta y Node-RED MQTT con TLS.
Clientes de línea de comandos de mosquitto
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u YOUR_USERNAME -P YOUR_PASSWORD -i YOUR_CLIENT_ID_cli \
-t 'site1/#' -v
En Windows o macOS, usa --cafile con un bundle PEM que contenga ISRG Root X1 en lugar de --capath.
Solución de problemas de conexión
| Síntoma | Causa probable | Solución |
|---|---|---|
| Not authorized / usuario o contraseña incorrectos | Se siguen usando las credenciales antiguas de HiveMQ | Copia las nuevas credenciales desde el portal |
| Conexión rechazada justo después del CONNECT | El client ID no coincide con el ID emitido ni con el patrón _sufijo |
Usa YOUR_CLIENT_ID o YOUR_CLIENT_ID_<suffix> |
| Dos dispositivos se desconectan mutuamente | Ambos usan el mismo client ID | Deriva un sufijo único de la MAC o del número de serie |
| Fallo en el handshake TLS | Al almacén de confianza del dispositivo le falta ISRG Root X1, o el reloj es incorrecto | Añade el certificado raíz y sincroniza la hora. Consulta fallo del handshake TLS en MQTT |
| El navegador no se conecta | Puerto o ruta de WebSocket incorrectos | Usa wss://broker.connectmq.com:8084/mqtt |
| La conexión funciona, pero se rechazan las publicaciones | QoS 2 o payload por encima del límite del plan | Usa QoS 1 en Serverless (Free), mantén los payloads por debajo de 256 KB o amplía el plan |
Reason code 0x97 |
Se ha superado la cuota de conexiones del plan | Amplía el plan antes de la siguiente oleada |
Facilita el próximo cambio
Ya que vas a editar todos los clientes, traslada el hostname, el puerto, las credenciales y el client ID a una configuración que pueda actualizarse en remoto: un archivo de configuración, variables de entorno, un servicio de aprovisionamiento o un payload de ajustes por OTA. Así, rotar credenciales o cambiar de broker en el futuro será un envío de configuración, no un proyecto de firmware.
Puedes probar cualquiera de estos ejemplos ahora mismo contra un broker gratuito en app.connectmq.com.
Preguntas frecuentes
¿Tengo que cambiar mis topics al dejar HiveMQ Cloud?
No. Los topics, los payloads y los niveles de QoS siguen igual. Solo cambian los ajustes de conexión.
¿Por qué ConnectMQ exige un client ID concreto?
Vincular los client IDs a las credenciales impide que otro inquilino o una credencial filtrada suplanten a tus dispositivos. Aun así, puedes ejecutar muchos clientes con un mismo conjunto de credenciales añadiendo un sufijo único.
¿El puerto 8883 es el mismo en ambos brokers?
Sí, MQTT sobre TLS usa el 8883 en los dos. El puerto de WebSocket seguro es distinto: ConnectMQ usa el 8084 con la ruta /mqtt.
¿Puedo seguir usando setInsecure en el ESP32?
Se conectará, pero se salta la verificación del servidor y expone los dispositivos a suplantaciones. Usa en su lugar el certificado ISRG Root X1.



