Publicado en

WebSockets: comunicación en tiempo real

Diagrama de comunicación WebSocket bidireccional entre cliente y servidor con mensajes fluyendo en ambas direcciones

HTTP funciona siempre igual: el cliente pregunta y el servidor responde. La conexión se abre, se intercambia un mensaje y se cierra. Pero hay aplicaciones donde ese modelo no encaja: un chat donde los mensajes llegan en cualquier momento, un dashboard con datos actualizándose en tiempo real, o un juego multijugador. En estos casos, necesitas que el servidor pueda hablar con el cliente sin esperar a que le pregunten. Para eso existen los WebSockets.

HTTP vs WebSocket

Comparación entre HTTP donde el cliente siempre inicia cada ciclo petición-respuesta y WebSocket donde la conexión persiste y ambos extremos envían mensajes cuando quieren

La diferencia es estructural. HTTP es un protocolo half-duplex: en cada ciclo solo hay un emisor (el cliente) y un receptor (el servidor). WebSocket es full-duplex: ambos extremos pueden enviar datos a la vez, en cualquier momento, sin esperar al otro.

En HTTP, si quieres que una página muestre datos actualizados cada pocos segundos, necesitas hacer polling: el cliente pregunta repetidamente al servidor, la mayoría de las veces recibiendo la misma respuesta. Es ineficiente. WebSocket elimina ese problema con una única conexión persistente.

El handshake: cómo se establece la conexión

Una conexión WebSocket empieza siendo HTTP. El cliente envía una petición HTTP normal con cabeceras especiales indicando que quiere hacer upgrade al protocolo WebSocket:

GET /chat HTTP/1.1
Host: servidor.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Si el servidor acepta, responde con 101 Switching Protocols y la conexión TCP subyacente pasa a funcionar con el protocolo WebSocket:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

A partir de ese momento la conexión permanece abierta y ambos extremos pueden enviar frames (la unidad mínima de datos de WebSocket) en cualquier momento.

Mensajes y eventos

La API de WebSocket en el cliente es sencilla. Tiene cuatro eventos principales:

const ws = new WebSocket("wss://servidor.com/chat");
 
ws.onopen = () => {
  console.log("Conexión establecida");
  ws.send("Hola, servidor");
};
 
ws.onmessage = (evento) => {
  console.log("Mensaje recibido:", evento.data);
};
 
ws.onclose = (evento) => {
  console.log("Conexión cerrada, código:", evento.code);
};
 
ws.onerror = (error) => {
  console.error("Error WebSocket:", error);
};

Nota el prefijo wss:// (WebSocket Secure), el equivalente de https:// para WebSocket. Siempre debe usarse en producción; ws:// transmite los datos en claro.

En el servidor, la implementación depende del lenguaje y la librería, pero el concepto es el mismo: manejar los eventos de conexión, mensaje y cierre.

// Servidor (pseudo-código genérico)
servidor.alConectar((socket) => {
  socket.alMensaje((datos) => {
    // difundir a todos los clientes conectados
    clientes.paraEach(c => c.enviar(datos));
  });
 
  socket.alCerrar(() => {
    eliminar_de_lista(socket);
  });
});

Casos de uso

  • Chats y mensajería: el caso más obvio. Los mensajes llegan al instante sin polling.
  • Notificaciones en tiempo real: alertas de pedidos, menciones, cambios de estado que el servidor debe empujar al cliente.
  • Dashboards en vivo: métricas, precios de acciones, datos de sensores actualizándose continuamente.
  • Colaboración en tiempo real: varios usuarios editando el mismo documento, como Google Docs.
  • Juegos multijugador: posiciones, acciones y estado del juego sincronizados entre jugadores.

Cuándo no usar WebSockets

WebSocket no es siempre la mejor opción. Mantener conexiones persistentes tiene un coste en el servidor: cada conexión abierta consume un descriptor de archivo y memoria. Para algunos casos existe una alternativa más ligera.

  • SSE (Server-Sent Events): si solo necesitas que el servidor envíe datos al cliente (no al revés), SSE es más simple. Funciona sobre HTTP estándar, el cliente recibe un stream de eventos y no necesita enviar nada. Ideal para notificaciones, feeds de actividad o progreso de tareas largas.
  • Polling tradicional: si los datos cambian con poca frecuencia (cada minutos) y la latencia de segundos es aceptable, el polling HTTP simple es suficiente y más fácil de implementar, escalar y depurar.

La regla práctica: usa WebSocket cuando la comunicación sea genuinamente bidireccional y requiera baja latencia. Si solo necesitas que el servidor informe al cliente de vez en cuando, SSE es más adecuado y mucho más sencillo.

Con esto quedan cubiertos los fundamentos del desarrollo backend: qué es y cómo se estructura, cómo se diseñan APIs, cómo funciona HTTP, cómo se protege el acceso con autenticación y JWT, cómo se accede a los datos y cómo se mantiene una comunicación persistente con el cliente.