Concepto clave
Las WebSockets son un protocolo de comunicación bidireccional que permite conexiones persistentes entre cliente y servidor. A diferencia de HTTP, que sigue un ciclo de solicitud-respuesta, WebSockets mantienen un canal abierto donde ambos extremos pueden enviar datos en tiempo real sin necesidad de recargar la página.
Imagina una conversación telefónica: una vez establecida la llamada, ambas partes pueden hablar y escuchar simultáneamente, sin tener que colgar y marcar de nuevo para cada frase. Esto es exactamente lo que WebSockets proporciona a las aplicaciones web: una comunicación fluida y continua.
En el contexto de nuestra app de tareas, esto significa que cuando un usuario marca una tarea como completada, todos los demás usuarios conectados verán ese cambio instantáneamente, sin necesidad de refrescar manualmente la página. Es como trabajar en un documento compartido de Google Docs, donde los cambios de otros aparecen en vivo mientras escribes.
Cómo funciona en la práctica
Para implementar WebSockets en SvelteKit, seguiremos estos pasos:
- Configurar un servidor WebSocket en el backend de SvelteKit
- Establecer la conexión desde el cliente SvelteKit
- Enviar y recibir mensajes entre cliente y servidor
- Actualizar el estado de la aplicación en tiempo real
Veamos un ejemplo básico: cuando un usuario crea una nueva tarea, el servidor recibe esa información a través de WebSockets y la transmite inmediatamente a todos los clientes conectados. Cada cliente actualiza su interfaz para mostrar la nueva tarea, creando la ilusión de magia, pero en realidad es solo comunicación eficiente.
Código en acción
Primero, configuramos el servidor WebSocket en nuestro endpoint de SvelteKit:
// src/routes/api/websocket/+server.js
import { WebSocketServer } from 'ws';
let clients = new Set();
const wss = new WebSocketServer({ noServer: true });
wss.on('connection', (ws) => {
clients.add(ws);
ws.on('message', (data) => {
const message = JSON.parse(data);
// Broadcast a todos los clientes conectados
clients.forEach(client => {
if (client !== ws && client.readyState === 1) {
client.send(JSON.stringify(message));
}
});
});
ws.on('close', () => {
clients.delete(ws);
});
});
export function handleUpgrade(request, socket, head) {
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit('connection', ws, request);
});
}Ahora, en el cliente SvelteKit, conectamos y manejamos los mensajes:
<!-- src/routes/tasks/+page.svelte -->
<script>
import { onMount } from 'svelte';
let tasks = [];
let wsConnection;
onMount(() => {
// Conectar al WebSocket
wsConnection = new WebSocket('ws://localhost:5173/api/websocket');
wsConnection.onmessage = (event) => {
const updatedTask = JSON.parse(event.data);
// Actualizar tareas en tiempo real
tasks = tasks.map(task =>
task.id === updatedTask.id ? updatedTask : task
);
};
// Enviar actualizaciones cuando el usuario cambia una tarea
function updateTaskStatus(taskId, completed) {
const updatedTask = { id: taskId, completed };
wsConnection.send(JSON.stringify(updatedTask));
}
});
</script>Errores comunes
- No manejar reconexiones: Las conexiones WebSocket pueden caerse. Implementa lógica de reconexión automática con backoff exponencial.
- Enviar datos sin validar: Siempre valida y sanitiza los mensajes entrantes en el servidor para prevenir inyecciones.
- Olvidar limpiar conexiones: En SvelteKit, asegúrate de cerrar las conexiones WebSocket en el ciclo de vida del componente (onDestroy) para evitar fugas de memoria.
- No considerar escalabilidad: Para aplicaciones grandes, considera usar Redis Pub/Sub o servicios como Socket.io en lugar de WebSockets nativos.
- Ignorar el estado de la conexión: Muestra indicadores visuales cuando la conexión se pierde o se está reconectando.
Checklist de dominio
- Puedo explicar la diferencia entre HTTP y WebSockets en una frase
- He implementado un servidor WebSocket básico en SvelteKit
- Sé cómo manejar mensajes entrantes y salientes en el cliente
- Puedo implementar reconexión automática cuando la conexión se pierde
- Entiendo cómo broadcastear mensajes a múltiples clientes
- Sé limpiar adecuadamente las conexiones WebSocket
- Puedo integrar WebSockets con el estado de mi aplicación SvelteKit
Implementa notificaciones en tiempo real para tareas compartidas
En este ejercicio, extenderás la app de tareas para que cuando un usuario marque una tarea como completada, todos los demás usuarios en la misma lista vean el cambio instantáneamente.
- Modifica el servidor WebSocket existente para que almacene las conexiones por lista de tareas (room)
- Cuando un usuario se conecte, envía su ID de lista para unirlo a la room correspondiente
- Implementa la lógica para que los mensajes solo se broadcasten a usuarios en la misma room
- En el cliente, actualiza la interfaz cuando lleguen mensajes de WebSocket
- Añade un indicador visual (como un badge) que muestre cuántos usuarios están conectados a la misma lista
Entrega: Un repositorio Git con los cambios implementados y un README que explique tu solución.
Pistas- Usa un Map para almacenar las rooms y sus conexiones
- Considera enviar el roomId como parámetro en la conexión WebSocket
- Puedes usar localStorage para persistir el roomId entre sesiones
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.