WebSockets para Comunicación en Tiempo Real
Construye comunicación bidireccional en tiempo real con WebSockets, manejando gestión de conexiones, reconexión y fallbacks.
Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.
Visión General
WebSockets proveen comunicación full-duplex persistente entre navegadores y servidores sobre una sola conexión TCP. A diferencia del polling HTTP, los WebSockets habilitan flujo de datos en tiempo real con latencia mínima, haciéndolos ideales para chat, dashboards en vivo, juegos multijugador y edición colaborativa.
Cuándo Usar
Usa este recurso cuando:
- Construyas aplicaciones de chat o sistemas de comentarios en vivo
- Streamings de datos en tiempo real a dashboards (acciones, métricas, IoT)
- Implementes sincronización de estado de juegos multijugador
- Crees herramientas de edición colaborativa (como Google Docs)
Solución
Servidor con ws (Node.js)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
const clients = new Set();
wss.on('connection', (ws, req) => {
clients.add(ws);
ws.on('message', (data) => {
const message = JSON.parse(data);
clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({
type: 'chat',
from: message.user,
text: message.text,
timestamp: Date.now()
}));
}
});
});
ws.on('close', () => clients.delete(ws));
});
Lógica de Reconexión del Cliente
class ReconnectingWebSocket {
constructor(url) {
this.url = url;
this.ws = null;
this.reconnectInterval = 3000;
this.maxReconnectInterval = 30000;
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
this.reconnectInterval = 3000;
};
this.ws.onclose = () => {
setTimeout(() => this.connect(), this.reconnectInterval);
this.reconnectInterval = Math.min(
this.reconnectInterval * 2,
this.maxReconnectInterval
);
};
}
send(data) {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(data));
}
}
}
Explicación
El handshake de WebSocket actualiza una conexión HTTP:
- El cliente envía un request de upgrade con headers Connection: Upgrade y Upgrade: websocket
- El servidor responde 101 Switching Protocols para confirmar
- Frames bidireccionales se intercambian sobre el socket TCP persistente
- Handshake de cierre termina la conexión limpiamente
Diferencias clave con SSE:
- WebSockets son bidireccionales; SSE es solo servidor-a-cliente
- WebSockets usan frames binarios; SSE usa text/event-stream
- WebSockets necesitan heartbeat/ping propio; SSE usa HTTP keep-alive
Variantes
| Tecnología | Dirección | Ideal Para |
|---|---|---|
| WebSockets | Bidireccional | Chat, juegos, colaboración |
| SSE | Servidor-a-cliente | Feeds en vivo, notificaciones |
| Long Polling | Servidor-a-cliente | Soporte de navegadores legacy |
| MQTT sobre WebSocket | Pub/sub | IoT, telemetría |
Mejores Prácticas
- Implementa heartbeat/ping: Detecta conexiones muertas con frames ping/pong periódicos
- Autentica durante el handshake: Pasa JWT en query string o subprotocolo
- Usa rooms/canales: No transmitas todo a todos los clientes
- Maneja backpressure: Descarta o encola mensajes si los clientes son lentos
- Fallback a SSE: Para clientes detrás de proxies estrictos que bloquean WebSockets
Errores Comunes
- Sin lógica de reconexión: Problemas de red desconectan permanentemente a los usuarios
- Broadcasting a todos: No escala; usa pub/sub o salas de canal
- Ignorar fugas de memoria: Conexiones cerradas no removidas del set de clientes causan OOM
- Enviar binario sin framing: Siempre serializa datos estructurados (JSON, Protobuf)
- No manejar timeouts de proxy: Proxies corporativos pueden matar conexiones inactivas después de 30s
Preguntas Frecuentes
P: ¿Cuántas conexiones WebSocket concurrentes puede manejar un servidor? R: Node.js maneja ~10k-50k conexiones por core. Usa Redis pub/sub o un message bus para escalar horizontalmente.
P: ¿Funcionan WebSockets sobre HTTPS? R: Sí — usa wss:// (WebSocket Secure). Los navegadores bloquean ws:// mixto en páginas HTTPS.
P: ¿Cuál es el mejor fallback si WebSockets están bloqueados? R: Server-Sent Events para servidor-a-cliente; HTTP long polling para necesidades bidireccionales.
Recursos Relacionados
Server-Sent Events with Node.js and Express
Implement real-time server-to-client push using Server-Sent Events in Node.js with Express, covering connection management, event types, reconnection logic, and backpressure handling
RecipeBuild a Bidirectional Chat with WebSocket and Node.js
How to build a real-time bidirectional chat application using WebSocket with room-based messaging, presence tracking, and message persistence
PatternMVC Pattern in Modern Frontend Applications
Apply the Model-View-Controller pattern to React and Vue applications to separate data, UI, and interaction logic for maintainable component architecture
RecipeExpress.js Middleware Composition Patterns
Build maintainable Express applications using middleware composition patterns for authentication, validation, error handling, request context propagation, and async route wrappers
RecipeURL Encoding and Decoding: encodeURI, encodeURIComponent, and Beyond
Master URL encoding in JavaScript and other languages with encodeURI, encodeURIComponent, plus-safe handling, RFC 3986 compliance, and decoding edge cases