Hay aplicaciones web que funcionan, pero que funcionan mal. No porque el código esté roto, sino porque la arquitectura con la que fueron concebidas no es la adecuada para lo que se les pide. Este fue exactamente el caso de uno de nuestros clientes del sector de la alimentación y bebidas: una aplicación que necesitaba mostrar datos en tiempo real pero que, por debajo, seguía un patrón de consulta constante al servidor que la hacía lenta, ineficiente y difícil de escalar.

 

Necesidad inicial

El cliente disponía de una aplicación web que necesitaba mostrar información actualizada al usuario de forma continua. El problema era que el sistema no estaba diseñado para eso: cada vez que quería saber si había datos nuevos, la aplicación tenía que preguntar al servidor, esperar respuesta y repetir el proceso en bucle. Un patrón que genera carga innecesaria, introduce latencia y no escala bien cuando el número de usuarios crece.

La necesidad era clara: refactorizar la web para que el servidor pudiera enviar datos al cliente en el momento en que estos estuvieran disponibles, sin que la aplicación tuviera que estar preguntando constantemente.

 

Aplicación web preguntando constantemente si hay datos nuevos

El patrón que seguía la aplicación se conoce como polling: el cliente lanza una petición HTTP al servidor cada cierto intervalo de tiempo para comprobar si hay información nueva. Es una solución sencilla de implementar, pero tiene un coste muy real.

Cada petición consume recursos en el servidor aunque no haya nada nuevo que devolver. Si hay cien usuarios conectados, son cien peticiones por cada ciclo de polling, independientemente de si los datos han cambiado o no. El resultado es un servidor que trabaja constantemente, una aplicación que introduce un retardo entre el momento en que el dato está disponible y el momento en que el usuario lo ve, y un sistema que se vuelve cada vez más difícil de sostener a medida que crece la carga.

Además, este patrón obliga a encontrar un equilibrio incómodo entre frecuencia y rendimiento: si el intervalo es corto, la carga en el servidor es alta; si es largo, la información llega tarde al usuario. No hay forma de ganar sin cambiar el enfoque.

blank

 

Arquitectura de la solución para admitir comunicación bidireccional en tiempo real

La solución pasaba por sustituir el modelo de polling por una arquitectura que permitiera al servidor notificar al cliente en cuanto hubiera datos nuevos, sin necesidad de que este tuviera que preguntar.

MQTT sobre WebSockets como primer paso

El primer cambio fue introducir MQTT sobre WebSockets en la comunicación entre el Frontend y el Backend. A diferencia de HTTP, que abre una conexión, envía una petición, recibe una respuesta y la cierra, WebSockets establece un canal de comunicación persistente y bidireccional entre cliente y servidor. Una vez establecida la conexión, tanto el cliente como el servidor pueden enviarse mensajes en cualquier momento sin necesidad de iniciar una nueva petición. Esto elimina la latencia del polling y reduce drásticamente la carga en el servidor, ya que la conexión solo transporta información cuando realmente hay algo que comunicar.

MQTT es un protocolo de mensajería diseñado específicamente para entornos donde la eficiencia y la ligereza son críticas. Funciona sobre un modelo de publicación y suscripción: los productores de datos publican mensajes en un topic, y todos los suscriptores interesados en ese topic los reciben de forma inmediata, sin necesidad de que nadie pregunte. El broker MQTT actúa como intermediario, gestionando las suscripciones y distribuyendo los mensajes de forma eficiente entre todos los destinatarios.

Al combinarlo con WebSockets, conseguimos que este modelo de publicación y suscripción llegara directamente al navegador del usuario, cerrando el ciclo completo: desde la fuente de datos hasta la pantalla, todo en tiempo real y sin una sola petición de polling.

blank

Ventajas del uso de MQTT sobre WebSockets

En SETDEVELOPERS tenemos un enfoque preferencial por MQTT sobre WebSockets, y este proyecto es un buen ejemplo de por qué. La combinación de ambos protocolos ofrece ventajas concretas que ninguno de los dos da por separado.

La primera es la eficiencia. MQTT fue diseñado para minimizar el tamaño de los mensajes y el consumo de ancho de banda, con una cabecera mínima comparada con la de otros protocolos. Esto lo hace especialmente eficiente cuando hay muchos mensajes pequeños circulando de forma continua, que es exactamente el caso de una aplicación que muestra datos en tiempo real. A esto se suma la escalabilidad natural que ofrece el modelo de publicación y suscripción: cualquier número de clientes puede suscribirse a un topic sin que el productor del dato tenga que saber cuántos hay ni gestionarlos individualmente. Si mañana hay mil usuarios viendo los mismos datos, el sistema escala sin necesidad de cambiar nada en la arquitectura.

Otra ventaja importante es la resiliencia ante desconexiones. MQTT incluye mecanismos nativos para gestionar interrupciones temporales, como el sistema de mensajes retenidos y las sesiones persistentes, que permiten a un cliente recuperar los mensajes publicados durante su ausencia en cuanto vuelve a conectarse. Y por encima de todo esto, la arquitectura resultante queda preparada para crecer: centralizar la mensajería en un broker MQTT y exponerla a través de WebSockets hacia el Frontend permite integrar nuevas fuentes de datos, nuevos consumidores o nuevos canales sin tener que reescribir la lógica central.

El resultado para el cliente fue una aplicación que muestra datos en tiempo real sin latencia perceptible, con una carga en el servidor significativamente menor que con el polling y una arquitectura que puede crecer con el negocio sin convertirse en un cuello de botella.

Si tu aplicación web todavía está preguntando constantemente si hay datos nuevos, cuéntanos tu proyecto y analizamos juntos cómo modernizar su arquitectura.