Server-Sent Events en C++: Tiempo real sin magia ni bibliotecas innecesarias

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Por qué una solicitud HTTP normal es como una carta por correo, y SSE es un telegrama en tiempo real

\n\n

Imagine: está esperando una notificación sobre un nuevo comentario en un sitio web. Actualiza la página cada 5 segundos. El servidor devuelve cada vez un montón de HTML, CSS, imágenes — y solo entonces, al final, ve: «No hay nuevos comentarios». ¿Le suena? Esto se llama polling. Funciona, pero consume ancho de banda y sobrecarga el servidor.

\n\n

Ahora imagine otro escenario: abre una página y, un segundo después, aparece un mensaje: «Vasiliy dejó un comentario: "¡Artículo genial!"». Sin recargar, sin solicitudes adicionales. El servidor mismo le «empuja» los datos. Esto son los Server-Sent Events (SSE) — una tecnología que permite al servidor enviar al cliente un flujo de eventos a través de una conexión HTTP normal.

\n\n

En este artículo, analizaremos cómo implementar SSE en C++ puro sin usar frameworks pesados. Aprenderá por qué Server-Sent Events en C++ es una excelente opción para monitoreo, cotizaciones bursátiles, notificaciones de chat y cualquier tarea que requiera transmisión unidireccional de datos en tiempo real.

\n\n

¿Cómo funcionan los Server-Sent Events? Análisis del protocolo

\n\n

SSE es parte de la especificación HTML5. El cliente abre una conexión HTTP normal y le dice al servidor: «Estoy listo para escuchar eventos». En respuesta, el servidor no cierra la conexión, sino que comienza a enviar datos en un formato especial text/event-stream.

\n\n

El formato del mensaje es extremadamente simple:

\n\n
data: Este es el texto del evento\\n\\n
\n\n

Cada evento comienza con data: y termina con un doble salto de línea. Se puede agregar id: para identificación, event: para el tipo de evento y retry: para especificar el tiempo de reconexión en milisegundos.

\n\n

Ejemplo de un flujo completo:

\n\n
id: 42\nevent: new_message\ndata: {"user": "Vasiliy", "text": "¡Hola!"}\n\nid: 43\nevent: ping\ndata: El servidor está vivo\n\n
\n\n

El cliente (navegador o cualquier aplicación) procesa estas líneas y genera eventos de JavaScript. Todo lo ingenioso es simple.

\n\n

SSE vs WebSocket: ¿cuándo elegir qué?

\n\n

Muchos piensan inmediatamente en WebSocket cuando se trata de tiempo real. Comparemos:

\n\n
    \n
  • WebSocket — comunicación bidireccional. El cliente y el servidor pueden iniciar el intercambio. Requiere un protocolo separado (ws://), paso a través de proxies, a menudo bloqueado por firewalls corporativos.
  • \n
  • SSE — comunicación unidireccional (servidor → cliente). Funciona sobre HTTP normal. Se reconecta automáticamente en caso de interrupción. Pasa fácilmente a través de cualquier proxy.
  • \n
\n\n

Si su tarea es enviar notificaciones al cliente, y no esperar comandos de él, Server-Sent Events en C++ es una solución elegante y simple. No necesita arrastrar bibliotecas pesadas, ni escribir manejadores complejos.

\n\n

Escribimos un servidor SSE en C++ desde cero

\n\n

Para la implementación necesitamos un mínimo: sockets y trabajo con HTTP. En proyectos reales se usa Boost.Beast o libmicrohttpd, pero para entender la esencia escribiremos un servidor simple en C++ puro usando sockets POSIX.

\n\n

Nuestro servidor:

\n
    \n
  • Aceptará una solicitud HTTP del cliente
  • \n
  • Determinará que el cliente quiere SSE (por el encabezado Accept: text/event-stream)
  • \n
  • Enviará un flujo de eventos con la hora actual cada 2 segundos
  • \n
\n\n

Paso 1: Creamos un socket y escuchamos en un puerto

\n\n
#include <iostream>\n#include <string>\n#include <cstring>\n#include <unistd.h>\n#include <arpa/inet.h>\n#include <sys/socket.h>\n#include <thread>\n#include <chrono>\n#include <sstream>\n\nvoid handle_client(int client_socket) {\n    // Buffer para la solicitud\n    char buffer[4096] = {0};\n    read(client_socket, buffer, 4096);\n    \n    // Verificamos que sea una solicitud GE                

Blogs

Book Recommendations