Introducción a WebSocket y TypeScript para aplicaciones en tiempo real
\n\nLas aplicaciones web modernas requieren cada vez más un intercambio instantáneo de datos entre el cliente y el servidor. El protocolo HTTP tradicional, que funciona bajo el principio de «solicitud-respuesta», no es adecuado para tareas donde la velocidad de entrega de información es crítica: chats en línea, cotizaciones bursátiles, juegos multijugador o sistemas de monitoreo. Aquí es donde WebSocket viene al rescate: un protocolo que proporciona una conexión bidireccional permanente.
\n\nEn combinación con TypeScript, un superconjunto de JavaScript con tipado estricto, el desarrollo de aplicaciones WebSocket se vuelve no solo eficiente, sino también seguro. TypeScript permite detectar errores en la etapa de compilación, mejora la legibilidad del código y simplifica la refactorización. En este artículo, analizaremos el ciclo completo de creación de una aplicación en tiempo real con WebSocket y TypeScript: desde la teoría hasta ejemplos prácticos.
\n\nFundamentos de WebSocket: cómo funciona el protocolo
\n\n¿Qué es WebSocket?
\nWebSocket (RFC 6455) es un protocolo que establece una conexión permanente entre el cliente (navegador) y el servidor. Después del handshake (apretón de manos), los datos pueden transmitirse en ambas direcciones sin solicitudes HTTP repetidas. Esto reduce las latencias y la carga en la red.
\n\nDiferencia con HTTP
\n- \n
- HTTP: el cliente inicia una solicitud → el servidor responde → la conexión se cierra (o permanece abierta para las siguientes solicitudes, pero igualmente es iniciada por el cliente). \n
- WebSocket: después de establecer la conexión, el servidor puede enviar datos al cliente en cualquier momento (notificaciones push). \n
Ciclo de vida de una conexión WebSocket
\n- \n
- Handshake (Apretón de manos): el cliente envía una solicitud HTTP con el encabezado
Upgrade: websocket. El servidor responde con el código 101 Switching Protocols. \n - Intercambio de datos: después de un handshake exitoso, la conexión cambia al protocolo WebSocket. Los datos se transmiten en forma de tramas (frames). \n
- Cierre: cualquiera de las partes puede iniciar el cierre de la conexión enviando una trama de control especial. \n
Creación de un servidor WebSocket en TypeScript
\n\nElección de la biblioteca
\nPara la parte del servidor, usaremos la popular biblioteca ws, una implementación ligera y rápida de WebSocket para Node.js. La instalaremos junto con los tipos para TypeScript:
npm install ws\nnpm install -D @types/ws\n\nServidor básico
\nCrearemos un archivo server.ts:
import { WebSocketServer, WebSocket } from 'ws';\n\nconst PORT = 8080;\nconst wss = new WebSocketServer({ port: PORT });\n\nconsole.log(`Servidor WebSocket iniciado en ws://localhost:${PORT}`);\n\nwss.on('connection', (ws: WebSocket) => {\n console.log('Nueva conexión');\n\n // Enviamos un mensaje de bienvenida\n ws.send('¡Bienvenido al servidor!');\n\n // Manejo de mensajes entrantes\n ws.on('message', (message: Buffer) => {\n const text = message.toString();\n console.log(`Recibido: ${text}`);\n\n // Respuesta eco\n ws.send(`Eco: ${text}`);\n });\n\n // Manejo del cierre de conexión\n ws.on('close', () => {\n console.log('Cliente desconectado');\n });\n\n // Manejo de errores\n ws.on('error', (error: Error) => {\n console.error('Error de WebSocket:', error);\n });\n});\n\nManejo de diferentes tipos de mensajes
\nEn aplicaciones reales, los mensajes suelen estar estructurados en formato JSON. Crearemos un manejador tipado:
\ninterface ChatMessage {\n type: 'message' | 'join' | 'leave';\n username: string;\n content?: string;\n timestamp: number;\n}\n\nwss.on('connection', (ws: WebSocket) => {\n ws.on('message', (data: Buffer) => {\n try {\n const msg: ChatMessage = JSON.parse(data.toString());\n \n switch (msg.type) {\n case 'join':\n console.log(`${msg.username} se ha unido`);