comunicacion-sse-nodejs

Cómo hacer SSE (Server Sent Events) con Node.js

En Node.js, podemos implementar Server-Sent Events de manera sencilla utilizando el módulo http estándar junto con el módulo EventEmitter. A continuación, veremos un ejemplo básico de cómo crear un servidor SSE y cómo enviar eventos al cliente.

Los Server-Sent Events (SSE, eventos enviados desde el servidor) son una tecnología que nos permite enviar actualizaciones en tiempo real desde el servidor al cliente mediante una comunicación unidireccional desde el servidor hacia el cliente.

A diferencia de los Websockets, que proporcionan una comunicación bidireccional, los SSE son ideales para escenarios donde solo necesitamos enviar actualizaciones desde el servidor al cliente.

Las ventajas de los Server-Sent Events son:

  • Simplicidad: Los SSE son fáciles de implementar tanto en el servidor como en el cliente, sin necesidad de bibliotecas externas.
  • Compatibilidad: Son compatibles con la mayoría de los navegadores modernos sin necesidad de bibliotecas o polyfills adicionales.
  • Reconexión Automática: En caso de desconexión, el navegador intentará automáticamente reconectarse al servidor, lo que garantiza una comunicación más estable.

Ejemplo de Server-Sent Events en Node.js

Vamos a ver un ejemplo básico de cómo crear un servidor SSE y cómo manejar eventos de conexión y mensajes.

Creación del Servidor SSE

Primero creamos un servidor SSE en Node.js, que gestione gestione las comunicaciones del cliente.

import http from 'http';

// Función para enviar eventos al cliente
function enviarEvento(res, evento, datos) {
  res.write(`event: ${evento}\n`);
  res.write(`data: ${JSON.stringify(datos)}\n\n`);
}

// Crear servidor HTTP
const server = http.createServer((req, res) => {
  // Encabezado para indicar que se envían eventos SSE
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  // Enviar un evento cada 5 segundos
  const intervalo = setInterval(() => {
    enviarEvento(res, 'mensaje', { mensaje: 'Hola desde el servidor' });
  }, 5000);

  // Manejar cierre de conexión del cliente
  req.on('close', () => {
    clearInterval(intervalo);
    console.log('Cliente desconectado');
  });
});

const puerto = 3030;
server.listen(puerto, () => {
  console.log(`Servidor SSE iniciado en http://localhost:${puerto}`);
});

En este ejemplo:

  • Se crea un servidor HTTP que escucha en el puerto 3000.
  • Cuando un cliente se conecta, el servidor establece el encabezado Content-Type como text/event-stream para indicar que se enviarán eventos SSE.
  • Cada 5 segundos, se envía un evento al cliente con un mensaje JSON.
  • Cuando un cliente se desconecta, se limpia el intervalo de envío de eventos.

Cliente Web SSE (Frontend)

En el lado del cliente, podemos usar JavaScript para recibir y manejar los eventos enviados por el servidor.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Cliente SSE</title>
</head>
<body>
  <div id="mensaje"></div>

  <script>
    const mensajeDiv = document.getElementById('mensaje');

    const evtSource = new EventSource('http://localhost:3030');

    evtSource.onmessage = function(event) {
      const datos = JSON.parse(event.data);
      mensajeDiv.innerHTML = 'Mensaje del servidor: ' + datos.mensaje;
    };

    evtSource.onerror = function(event) {
      console.error('Error de SSE:', event);
      evtSource.close();
    };
  </script>
</body>
</html>

En este ejemplo de cliente HTML, creamos un EventSource apuntando a nuestro servidor SSE en http://localhost:3030. Cuando el cliente recibe un evento (onmessage), actualizamos el contenido de un elemento HTML con la hora actual enviada desde el servidor.

Para probarlo:

  1. Ejecuta el servidor Node.js que envía eventos SSE.
  2. En un navegador, accede a la dirección localhost:3030
  3. Deberías ver que el mensaje del servidor se actualiza cada 5 segundos en la página.

sse-example

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github github-full