Un broker MQTT para apps móviles permite que un teléfono vea los datos de un dispositivo en el momento en que cambian y envíe comandos de vuelta con muy poca sobrecarga. Esta guía explica cómo deben conectarse las apps móviles, cuándo MQTT es la herramienta adecuada y cuándo lo son las notificaciones push de la plataforma, cómo mantener bajo el consumo de batería y cómo gestionar las credenciales de forma segura, con un ejemplo funcional contra ConnectMQ.
Por qué las apps móviles usan MQTT
Las apps IoT móviles suelen necesitar tres cosas: mostrar el estado en vivo (¿está cerrada la puerta?, ¿qué nivel tiene el depósito?), enviar comandos (encender la bomba) y reaccionar rápido a los cambios. Consultar una API REST cada pocos segundos cumple mal las tres: desperdicia batería y datos, añade latencia y carga tu backend. MQTT mantiene abierta una única conexión de larga duración mientras la app está activa y envía solo lo que ha cambiado.
El broker en medio desacopla la app de los dispositivos. El teléfono nunca necesita la dirección IP de un dispositivo; ambos lados hablan con un endpoint conocido. Si este papel te resulta nuevo, lee primero qué hace un broker MQTT.
Opciones de conexión desde un teléfono
| Transporte | URL | Cuándo usarlo |
|---|---|---|
| MQTT sobre TLS | mqtts://broker.connectmq.com:8883 |
Apps nativas con una biblioteca MQTT capaz de usar TCP (Kotlin, Swift, Flutter) |
| MQTT sobre Secure WebSocket | wss://broker.connectmq.com:8084/mqtt |
React Native, Ionic, PWA y webviews; redes que bloquean el 8883 |
Ambos van cifrados y ambos funcionan con MQTT 3.1.1 y 5.0. WebSocket suele ser el camino con menos fricción en apps basadas en JavaScript y en redes Wi-Fi restrictivas; TLS nativo es ligeramente más eficiente. Nunca uses los puertos sin cifrar 1883 u 8083 desde una app en producción. La guía de MQTT sobre WebSocket explica en profundidad el transporte WebSocket.
MQTT frente a notificaciones push
Esta es la decisión de diseño más importante, y la respuesta suele ser "ambos".
| Necesidad | MQTT | Push de la plataforma (APNs / FCM) |
|---|---|---|
| Actualizaciones en vivo con la app abierta | Excelente | Encaja mal |
| Alertas con la app cerrada | No es fiable | Pensado para esto |
| Comandos bidireccionales | Sí | No |
| Coste de batería en segundo plano | Alto si se mantiene abierta | Lo gestiona el sistema operativo |
| Entrega con el teléfono desconectado | Sesión persistente mientras dure | La plataforma lo pone en cola |
Los sistemas operativos móviles suspenden las apps en segundo plano y sus sockets. iOS en particular no te permite mantener una conexión MQTT abierta indefinidamente en segundo plano. Así que la arquitectura robusta es:
- Primer plano: la app se conecta al broker, se suscribe a los dispositivos que el usuario está viendo y envía comandos por MQTT.
- Segundo plano: la app se desconecta limpiamente. Un pequeño servicio de backend se suscribe a los topics de alerta en el broker y envía notificaciones push de la plataforma cuando ocurre algo importante.
- Vuelta a primer plano: la app se reconecta, los retained messages entregan de inmediato el estado actual y la interfaz queda al día en un instante.
El relé de backend del paso 2 es simplemente otro cliente MQTT que ejecutas tú, por ejemplo un servicio en Node.js o Python. ConnectMQ no envía notificaciones push por sí mismo, y mantener esa lógica en tu propio servicio te da control sobre qué eventos se convierten en notificaciones.
Consideraciones de batería y datos
- Conéctate solo cuando haga falta. Abre la conexión cuando aparezca la pantalla correspondiente y ciérrala cuando la app pase a segundo plano.
- Suscríbete de forma acotada. Suscríbete a
home/42/devices/+/state, no a#. Cada mensaje que recibes cuesta tiempo de radio. - Usa retained messages para el estado. La app obtiene el último valor conocido al instante al suscribirse, así que nunca necesitas sondear ni pedir una actualización.
- Elige un keep alive moderado. De 30 a 60 segundos equilibra la detección rápida de conexiones muertas con menos despertares de la radio.
- Mantén los payloads compactos. Claves JSON cortas o codificaciones binarias ayudan en enlaces móviles.
- Usa topic aliases y caducidad de mensajes de MQTT 5 cuando estén disponibles. Los alias acortan los nombres de topic largos repetidos; la caducidad de mensajes evita que se entreguen tarde comandos obsoletos.
- Aplica backoff al reconectar. Las redes móviles cambian constantemente; el backoff exponencial evita bucles de reintento ajustados que agotan la batería.
Ejemplo funcional: React Native o web con MQTT.js
MQTT.js funciona en navegadores y en React Native sobre WebSocket. Este módulo encapsula la conexión, la suscripción y la gestión del ciclo de vida de la app.
import mqtt from "mqtt";
const BROKER_URL = "wss://broker.connectmq.com:8084/mqtt";
export function createDeviceConnection({ clientId, username, password, homeId, onState }) {
const client = mqtt.connect(BROKER_URL, {
clientId,
username,
password,
protocolVersion: 5,
keepalive: 45,
clean: true,
reconnectPeriod: 3000,
connectTimeout: 10000,
});
const stateTopic = `homes/${homeId}/devices/+/state`;
client.on("connect", () => {
client.subscribe(stateTopic, { qos: 1 }, (err) => {
if (err) console.warn("Subscribe failed", err.message);
});
});
client.on("message", (topic, payload) => {
const deviceId = topic.split("/")[3];
try {
onState(deviceId, JSON.parse(payload.toString()));
} catch {
console.warn("Ignoring non-JSON payload on", topic);
}
});
client.on("error", (err) => console.warn("MQTT error", err.message));
return {
sendCommand(deviceId, command) {
client.publish(
`homes/${homeId}/devices/${deviceId}/cmd`,
JSON.stringify(command),
{ qos: 1, properties: { messageExpiryInterval: 30 } }
);
},
pause() {
client.end(false);
},
resume() {
if (!client.connected) client.reconnect();
},
};
}
En React Native, llama a pause() y resume() desde un listener de cambios de AppState. La caducidad de mensaje de 30 segundos hace que un comando puesto en cola mientras un dispositivo está desconectado no se dispare inesperadamente minutos después. Algunas configuraciones de React Native necesitan un polyfill de WebSocket o de Buffer; consulta la guía de MQTT en React Native para los detalles de cada plataforma, y la de MQTT en Flutter si desarrollas con Dart.
Para probarlo sin cuenta, apúntalo al servidor MQTT público gratuito, omite el usuario y la contraseña, usa cualquier client ID único y no vacío y antepón a los topics un prefijo único como connectmq/demo/m7d2w/homes/.... Todo lo que hay en el área pública puede leerlo cualquiera, así que úsalo solo para demos y prototipos, nunca para datos de producción.
Gestionar las credenciales de forma segura
El binario de una app móvil se puede descompilar, así que trata como público todo lo que vaya incrustado en él.
- No incluyas en la app una única contraseña de broker compartida. Si se filtra, el tráfico de todos los usuarios queda expuesto y no puedes revocarla sin romper todas las instalaciones.
- Emite credenciales por usuario o por sesión desde tu backend. Cuando el usuario inicia sesión en tu app, tu API devuelve las credenciales MQTT y el client ID que debe usar ese usuario.
- Acota los topics por usuario o por hogar. Diseña los topics para que los datos de cada usuario estén bajo su propio prefijo, y controla en el dispositivo y en el backend qué comandos se aceptan y de quién.
- Rota y revoca. Cuando un usuario cierra sesión o pierde el teléfono, revoca sus credenciales.
- Valida los comandos en el dispositivo o en el backend. Nunca des por hecho que un comando procede de una pantalla legítima.
ConnectMQ vincula los client IDs a las credenciales emitidas y bloquea las IP tras inicios de sesión fallidos repetidos, lo que ayuda frente al credential stuffing. Lee buenas prácticas de seguridad en MQTT para ver la lista completa.
Planificación de capacidad para apps
Cada app abierta es una conexión. Diez dispositivos y cincuenta usuarios activos de la app son sesenta conexiones simultáneas en el pico, no diez. ConnectMQ Serverless (Free) permite hasta 25 conexiones, lo que sirve para desarrollo y una beta pequeña; Serverless (Paid) llega hasta 1.000 conexiones con QoS 2 y suscripciones compartidas; los clústeres dedicados atienden audiencias mayores. Como las apps se desconectan en segundo plano, las conexiones simultáneas suelen ser muchas menos que las instalaciones, pero mide tu patrón real en lugar de adivinarlo.
Para las opciones de hosting que hay detrás de estos planes, consulta la guía de broker MQTT en la nube.
Conecta tu app a ConnectMQ
Crea un broker Serverless gratuito en app.connectmq.com sin tarjeta de crédito, prueba tus topics en el cliente del navegador y apunta el ejemplo de MQTT.js a tu nuevo endpoint. ConnectMQ es un broker MQTT gestionado con endpoints TLS y Secure WebSocket listos para clientes móviles desde el primer minuto.
Preguntas frecuentes
¿Puede una app móvil mantener abierta una conexión MQTT en segundo plano?
No de forma fiable. Los sistemas operativos móviles suspenden los sockets en segundo plano, así que usa MQTT mientras la app está en primer plano y notificaciones push de la plataforma para las alertas en segundo plano.
¿Debe una app móvil usar WebSocket o TCP para MQTT?
Las apps basadas en JavaScript suelen usar Secure WebSocket en el puerto 8084 con la ruta /mqtt. Las apps nativas pueden usar TLS en el 8883; ambos van cifrados.
¿Cómo obtengo el estado actual del dispositivo al abrir la app?
Haz que los dispositivos publiquen su estado como retained messages. El broker entrega el último valor de inmediato cuando la app se suscribe.
¿Es seguro incrustar las credenciales del broker en una app móvil?
No. Emite credenciales por usuario desde tu backend tras el inicio de sesión, para que una credencial filtrada pueda revocarse de forma individual.



