Command Palette

Search for a command to run...

Server-Sent Events (SSE): Actualizaciones Unidireccionales del Servidor

Aprende a recibir actualizaciones en tiempo real del servidor usando EventSource y Server-Sent Events, ideal para feeds, notificaciones y datos en vivo.

Lectura: 12 min
Nivel: Intermedio

TL;DR - Resumen rápido

  • Server-Sent Events (SSE) es una API que permite al servidor enviar actualizaciones al cliente en tiempo real
  • SSE es unidireccional: solo el servidor puede enviar mensajes, el cliente solo recibe
  • EventSource es la API del navegador para establecer conexiones SSE
  • SSE usa HTTP estándar con Content-Type: text/event-stream
  • La reconexión automática es nativa en SSE, simplificando el manejo de desconexiones

Introducción a Server-Sent Events

Server-Sent Events (SSE) es una tecnología que permite a los servidores enviar datos al cliente en tiempo real a través de una conexión HTTP persistente. A diferencia de WebSocket que permite comunicación bidireccional, SSE es unidireccional: el servidor envía datos y el cliente solo los recibe. Esta característica hace que SSE sea ideal para escenarios donde necesitas actualizar información desde el servidor sin que el cliente envíe datos de vuelta.

SSE fue introducido como parte de HTML5 y está soportado por todos los navegadores modernos excepto Internet Explorer. La tecnología usa HTTP estándar con un Content-Type especial (text/event-stream) y un formato de mensaje simple basado en texto. Esta simplicidad hace que SSE sea fácil de implementar y depurar, y permite usar las mismas herramientas y proxies que ya existen para HTTP.

Cuándo usar SSE vs WebSocket

SSE es ideal cuando solo necesitas recibir actualizaciones del servidor (feeds de noticias, cotizaciones de acciones, notificaciones, dashboards en vivo). WebSocket es mejor cuando necesitas comunicación bidireccional (chat, juegos multijugador, colaboración en tiempo real). SSE es más simple de implementar, tiene reconexión automática nativa y funciona mejor con proxies y firewalls existentes.

¿Qué es Server-Sent Events?

Server-Sent Events es un estándar W3C que define cómo los servidores pueden enviar eventos al cliente a través de una conexión HTTP persistente. La conexión se establece usando una petición HTTP GET estándar, y el servidor mantiene la conexión abierta enviando eventos periódicamente. Cada evento tiene un formato específico con campos opcionales como data, event, id y retry.

  • <strong>Unidireccional</strong>: Solo el servidor puede enviar mensajes al cliente.
  • <strong>Texto plano</strong>: Los mensajes se envían como texto, ideal para JSON.
  • <strong>Reconexión automática</strong>: El navegador reconecta automáticamente si se pierde la conexión.
  • <strong>HTTP estándar</strong>: Funciona con proxies, firewalls y herramientas HTTP existentes.
  • <strong>Eventos tipados</strong>: Los eventos pueden tener tipos personalizados para categorizar mensajes.

El formato de mensaje SSE es simple y legible. Cada mensaje consiste en uno o más campos, cada uno en una línea separada. El campo data contiene el contenido del mensaje y puede tener múltiples líneas. El campo event especifica el tipo de evento, lo que permite al cliente escuchar eventos específicos. El campo id se usa para identificar eventos y facilita la reconexión, mientras que retry especifica el tiempo de reconexión en milisegundos.

Formato de mensaje SSE

Un mensaje SSE típico tiene este formato: data: contenido del mensaje seguido de una línea en blanco. Para eventos con tipo: event: tipo-evento y data: contenido. Los mensajes se separan con una línea en blanco. Los datos pueden ser texto plano o JSON, lo que facilita el intercambio de información estructurada.

API EventSource

La API EventSource es la interfaz del navegador para trabajar con Server-Sent Events. Para usarla, simplemente creas una instancia de EventSource con la URL del endpoint SSE. La API maneja automáticamente la conexión, el procesamiento de eventos y la reconexión en caso de desconexión, lo que simplifica significativamente el código del cliente.

EventSource proporciona varios eventos que puedes escuchar: open se dispara cuando se establece la conexión, message se dispara cuando se recibe un mensaje sin tipo específico, y error se dispara cuando ocurre un error en la conexión. También puedes escuchar eventos personalizados usando addEventListener con el nombre del evento especificado en el servidor.

eventsource-basico.js
Loading code...

Este código muestra cómo usar EventSource para recibir eventos del servidor. Al crear la instancia de EventSource, se establece automáticamente la conexión con el servidor. El evento message recibe todos los mensajes que no tienen un tipo específico, con los datos en event.data. El evento open indica que la conexión está establecida, mientras que error se dispara cuando hay problemas con la conexión. También puedes escuchar eventos personalizados usando addEventListener con el tipo del evento.

Limitación: solo GET y same-origin

EventSource solo usa peticiones GET y no permite enviar datos al servidor. Si necesitas enviar datos, usa parámetros en la URL o WebSocket. Además, por defecto, EventSource sigue la política de same-origin. Para conectarte a un origen diferente, el servidor debe configurar CORS apropiadamente con los headers Access-Control-Allow-Origin.

Establecer Conexión

Establecer una conexión SSE es tan simple como crear una instancia de EventSource con la URL del endpoint. La conexión se establece automáticamente usando una petición HTTP GET, y el servidor debe responder con Content-Type: text/event-stream para indicar que está enviando eventos SSE. Una vez establecida la conexión, el servidor puede enviar eventos en cualquier momento.

La conexión SSE es persistente, lo que significa que permanece abierta mientras tanto el cliente como el servidor la mantengan. El navegador maneja automáticamente la reconexión si se pierde la conexión, usando un algoritmo de backoff exponencial que comienza con 3 segundos y aumenta hasta 30 segundos. Esta reconexión automática es una de las principales ventajas de SSE sobre otras técnicas de comunicación en tiempo real.

establecer-conexion.js
Loading code...

Este código muestra cómo establecer una conexión SSE con diferentes configuraciones. Puedes pasar parámetros en la URL para filtrar o personalizar los eventos que recibes. La propiedad readyState indica el estado de la conexión: 0 es CONNECTING, 1 es OPEN y 2 es CLOSED. El método close() cierra la conexión explícitamente y detiene la reconexión automática.

Mejor práctica: close() cuando no se necesite

Siempre llama a eventSource.close() cuando ya no necesites recibir eventos, como cuando el usuario navega a otra página o cierra el componente. Esto libera recursos y detiene la reconexión automática, evitando conexiones zombies que consumen ancho de banda y recursos del servidor innecesariamente.

Tipos de Eventos

SSE soporta eventos con tipos personalizados, lo que permite categorizar mensajes y escuchar solo los tipos que te interesan. El servidor puede especificar el tipo de evento usando el campo event: en el mensaje. En el cliente, puedes escuchar eventos específicos usando addEventListener con el nombre del evento, o escuchar todos los mensajes usando el evento message.

Los eventos con tipos personalizados son útiles cuando tienes diferentes categorías de información que quieres manejar de forma diferente. Por ejemplo, en un dashboard de monitoreo, podrías tener eventos de tipo alert para alertas críticas, metric para métricas de rendimiento, y status para actualizaciones de estado. Cada tipo de evento puede tener su propio handler específico.

eventos-tipos.js
Loading code...

Este código muestra cómo escuchar diferentes tipos de eventos SSE. El evento message recibe todos los mensajes que no tienen un tipo específico. Los eventos personalizados se escuchan usando addEventListener con el nombre del evento. Los datos del mensaje están en event.data, y event.lastEventId contiene el ID del último evento recibido, útil para reconexión. Esto permite manejar diferentes tipos de información de forma específica, mejorando la organización y mantenibilidad del código.

Mejor práctica: validar datos

Siempre valida los datos recibidos en los eventos SSE, especialmente cuando se espera JSON. Usa try-catch al parsear JSON y verifica que los campos requeridos estén presentes. Esto previene errores cuando el servidor envía datos malformados o cuando hay cambios en el formato de los mensajes.

Manejo de Reconexión

Una de las características más poderosas de SSE es la reconexión automática nativa. Cuando se pierde la conexión, el navegador intenta reconectar automáticamente usando un algoritmo de backoff exponencial que comienza con 3 segundos y aumenta hasta 30 segundos. Esto simplifica significativamente el código del cliente, ya que no necesitas implementar lógica de reconexión manual.

El servidor puede controlar el comportamiento de reconexión usando el campo retry en los mensajes SSE, que especifica el tiempo de reconexión en milisegundos. El campo id se usa para identificar eventos y facilita la reconexión: cuando el cliente se reconecta, envía el Last-Event-ID header con el ID del último evento recibido, permitiendo al servidor reenviar eventos perdidos.

reconexion-sse.js
Loading code...

Este código muestra cómo manejar la reconexión en SSE. El evento error se dispara cuando hay problemas con la conexión, y puedes verificar el estado de la conexión usando readyState. El navegador reconecta automáticamente si se pierde la conexión, usando backoff exponencial que aumenta de 3s a 30s. La propiedad lastEventId del evento contiene el ID del último evento recibido, que el navegador envía automáticamente en el header Last-Event-ID al reconectar, permitiendo al servidor reenviar eventos perdidos. El servidor puede especificar el tiempo de reconexión usando el campo retry en milisegundos.

Resumen: Server-Sent Events

Conceptos principales:

  • SSE es unidireccional: solo el servidor puede enviar mensajes al cliente
  • EventSource es la API del navegador para establecer conexiones SSE
  • SSE usa HTTP estándar con Content-Type: text/event-stream
  • Los eventos pueden tener tipos personalizados para categorizar mensajes
  • La reconexión automática es nativa en SSE con backoff exponencial

Mejores prácticas:

  • Usa SSE cuando solo necesitas recibir actualizaciones del servidor
  • Llama a close() cuando ya no necesites recibir eventos para liberar recursos
  • Valida los datos recibidos, especialmente cuando se espera JSON
  • Usa eventos con tipos personalizados para organizar mejor el código
  • Configura CORS apropiadamente en el servidor para conexiones cross-origin