Server-Sent Events en Java: cuando WebSocket es demasiado y HTTP no es suficiente
\n\n¿Alguna vez te has preguntado cómo funcionan los feeds de noticias en Twitter, las notificaciones en Telegram o los resultados en vivo de partidos deportivos? Parece que los datos llegan solos, sin necesidad de recargar la página. El secreto es simple: Server-Sent Events (SSE) — una tecnología que permite al servidor enviar datos al cliente en tiempo real a través de una conexión HTTP normal.
\n\nEn este artículo analizaremos Server-Sent Events en Java. Descubrirás por qué SSE suele ser más conveniente que WebSocket, cómo configurar el servidor con Java Servlet API y cómo recibir eventos en el cliente. El código será funcional, el estilo dinámico y los ejemplos lo más cercanos posible a tareas reales.
\n\n¿Qué son Server-Sent Events y para qué sirven?
\n\nServer-Sent Events (SSE) es un estándar W3C que permite al servidor "enviar" datos al cliente a través de una única conexión HTTP de larga duración. El cliente se suscribe a un flujo de eventos y el servidor envía mensajes a medida que aparecen.
\n\nSSE es ideal para:
\n- \n
- Notificaciones — nuevos correos, mensajes, cambios de estado. \n
- Feeds de noticias — publicaciones, tweets, tipos de cambio. \n
- Monitoreo — registros, métricas del servidor, progreso de tareas. \n
- Datos en vivo — cotizaciones de acciones, resultados de partidos, clima. \n
A diferencia de WebSocket, SSE funciona solo en una dirección (servidor → cliente), pero esto es suficiente para la mayoría de los escenarios. Además, SSE utiliza HTTP normal, no requiere puertos adicionales y atraviesa fácilmente proxies y firewalls.
\n\nServer-Sent Events vs WebSocket: ¿qué elegir?
\n\nSi solo necesitas enviar datos del servidor al cliente (sin comunicación bidireccional), elige SSE. Es más simple, ligero y económico. WebSocket está justificado cuando el cliente también envía datos activamente (por ejemplo, en chats o juegos en línea).
\n\n| Criterio | \nServer-Sent Events | \nWebSocket | \n
|---|---|---|
| Dirección | \nServidor → Cliente | \nBidireccional | \n
| Protocolo | \nHTTP/1.1, HTTP/2 | \nws:// o wss:// | \n
| Reconexión automática | \nSí (integrada en el navegador) | \nNo (debe implementarse) | \n
| Complejidad de implementación | \nBaja | \nMedia/Alta | \n
| Soporte de navegadores | \nTodos los modernos | \nTodos los modernos | \n
Para el sitio educativo PythonLib, elegimos Java porque es un lenguaje confiable para el desarrollo del lado del servidor. ¡Allá vamos!
\n\nParte del servidor: implementación de SSE en Java con Servlet API
\n\nEmpecemos con el servidor. La forma más sencilla es usar Java Servlets estándar. Necesitamos:
\n- \n
- Establecer el encabezado
Content-Type: text/event-stream. \n - Deshabilitar el almacenamiento en caché (
Cache-Control: no-cache). \n - Mantener la conexión abierta. \n
- Enviar datos en el formato
data: ...\\n\\n. \n
Ejemplo 1: Servidor SSE simple con Java Servlet
\n\nCreemos un servlet que envíe la hora actual cada 5 segundos.
\n\nimport javax.servlet.ServletException;\nimport javax.servlet.annotation.WebServlet;\nimport javax.servlet.http.HttpServlet;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.time.LocalTime;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorServ