Streaming en HTTP

Cómo implementar una conexión HTTP de streaming en tiempo real para enviar datos desde el servidor al cliente a medida que se van generando.

streaming-http

Para enviar datos de forma continua desde el servidor al navegador usar WebSockets es quizá lo primero que le viene a uno a la mente, pero hay una alternativa menos compleja y sencilla de implementar. En el protocolo HTTP estándar existe una forrma para establecer esta comunicación enviando y recibiendo datos poco a poco sin cerrar la conexión.

Vamos a ver en qué consiste exactamente el streaming en HTTP, cuándo tiene sentido usarlo y cómo implementarlo en un flujo cliente-servidor con JavaScript y Node.js.

¿Qué es el streaming HTTP?

Cuando hablamos de streaming HTTP nos referimos a la posibilidad de que el servidor envíe datos al cliente en múltiples fragmentos (o chunks), manteniendo la conexión abierta, en lugar de enviar todo el contenido de una vez y cerrarla. Esto resulta útil para interfaces que deben reaccionar en tiempo real a cambios en el estado de la aplicación (por ejemplo, actualizaciones de sensores, mensajes en directo, logs, etc.).

Aunque no permite comunicación bidireccional como WebSockets, su simplicidad lo hace adecuado para muchas situaciones donde sólo necesitamos que el servidor envíe datos al cliente.

Ejemplo práctico: lectura progresiva en el cliente

Vamos a partir de este ejemplo de código en el cliente en el que se abre una conexión a una ruta /stream para iniciar la transferencia de datos:

const response = await fetch("/stream");
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
updateState(chunk);
}

Este patrón permite leer la respuesta HTTP en tiempo real. fetch obtiene el cuerpo de la respuesta como ReadableStream, y con getReader() accedemos a los fragmentos según vayan llegando. El bucle espera cada nuevo bloque de datos antes de seguir, y updateState() puede actualizar el DOM, un gráfico o cualquier otra parte de la aplicación con la nueva información.

Cómo preparar el servidor en Node.js

Veamos ahora cómo podemos construir el servidor para que este cliente funcione correctamente. Usaremos Node.js con Express, que permite controlar las cabeceras y enviar datos manualmente.

const express = require("express");
const app = express();
app.get("/stream", (req, res) => {
res.setHeader("Content-Type", "text/plain; charset=utf-8");
res.setHeader("Transfer-Encoding", "chunked");
res.setHeader("Cache-Control", "no-cache");
const interval = setInterval(() => {
const data = `Estado actualizado: ${new Date().toISOString()}\n`;
res.write(data);
}, 2000); // enviamos cada 2 segundos
req.on("close", () => {
clearInterval(interval);
res.end();
});
});
app.listen(3000, () => {
console.log("Servidor escuchando en http://localhost:3000");
});

Con res.write() enviamos cada fragmento. La conexión permanece abierta hasta que el cliente se desconecta o hasta que decidamos cerrarla manualmente. Es importante configurar correctamente las cabeceras:

  • Transfer-Encoding: chunked permite que el servidor envíe datos en bloques sucesivos sin conocer el tamaño total de antemano.
  • Cache-Control: no-cache evita que el navegador o proxies intermedios almacenen la respuesta.
  • Content-Type se puede ajustar a application/json o cualquier otro formato según el tipo de datos.

Este patrón es compatible con cualquier navegador moderno que soporte ReadableStream, y no requiere librerías externas ni protocolos adicionales.

Cuándo tiene sentido usar este enfoque

Podemos recurrir al streaming HTTP cuando:

  • Necesitamos enviar datos del servidor al cliente de forma continua.
  • No hay interacción del cliente hacia el servidor mientras la transmisión está activa.
  • Queremos mantener una solución basada en HTTP sin WebSockets.

Algunos ejemplos típicos:

  • Visualización de logs en tiempo real.
  • Seguimiento de estado de procesos de backend (por ejemplo, compilaciones, cargas).
  • Aplicaciones de monitorización.

Conclusión

El streaming sobre HTTP es una técnica sencilla y útil para enviar datos en tiempo real desde el servidor al cliente sin necesidad de integrar WebSockets ni otras soluciones más complejas. Su implementación requiere entender cómo enviar bloques desde el backend y cómo leerlos progresivamente en el cliente.