3. Streaming de Respuestas en Tiempo Real con SSE (Server-Sent Events)
Construye la experiencia de usuario fluida tipo ChatGPT o Claude: transmisión continua de chunks con Server-Sent Events en PHP y JavaScript.
¿Por qué el Streaming es Obligatorio en Aplicaciones con IA?
La inferencia de un modelo de lenguaje requiere tiempo: generar un párrafo de 300 palabras puede tardar entre 4 y 12 segundos. Si esperas a que la respuesta esté 100% completada antes de enviar el JSON al navegador, el usuario experimentará una sensación de congelamiento y lentitud frustrante.
Con Streaming en Tiempo Real, el servidor web envía cada palabra o fragmento (chunk) al navegador tan pronto como el modelo lo genera. La métrica Time To First Token (TTFT) se reduce de varios segundos a menos de 300 milisegundos, ofreciendo el efecto máquina de escribir que los usuarios esperan.
Server-Sent Events (SSE) vs WebSockets
Aunque WebSockets permite comunicación bidireccional continua, para asistentes de IA y consumo de LLMs la tecnología estándar de la industria es Server-Sent Events (SSE):
| Característica | Server-Sent Events (SSE) ⭐ Recomendado | WebSockets |
|---|---|---|
| Dirección del Flujo | Unidireccional (Servidor ➔ Cliente tras petición HTTP estándar). | Bidireccional completa (Cliente ⇄ Servidor). |
| Protocolo & Proxies | HTTP/1.1 o HTTP/2 estándar (compatible con Nginx, Cloudflare, firewalls). | Requiere handshake de mejora de protocolo (Upgrade: websocket). |
| Formato del Stream | Texto plano con prefijo data: {JSON}\n\n y evento de cierre data: [DONE]. |
Tramas binarias o de texto arbitrarias. |
| Complejidad Backend | Mínima: no requiere servidores persistentes en Node/Go; funciona en PHP tradicional. | Alta: requiere daemon WebSocket en ejecución continua y socket rooms. |
X-Accel-Buffering: no y llamar a ob_flush() y flush() tras cada paquete.
⚡ Consumo de Stream SSE en el Frontend con JavaScript Moderno
Código JavaScript con Fetch API, ReadableStream y TextDecoder que lee los fragmentos continuos y los renderiza en tiempo real.
/**
* sse-streaming-client.js - Consumo en vivo con Fetch y ReadableStream
*/
async function streamAssistantReply(userPrompt, outputElement) {
outputElement.textContent = "";
try {
const response = await fetch("/api/chat-stream.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: userPrompt })
});
if (!response.ok) {
throw new Error(`HTTP Error ${response.status}: Fallo al conectar con el asistente`);
}
// Obtenemos el lector de flujos binarios del cuerpo HTTP
const reader = response.body.getReader();
const decoder = new TextDecoder("utf-8");
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
// Decodificamos el bloque binario a texto legible
buffer += decoder.decode(value, { stream: true });
// Dividimos las líneas según la especificación SSE (\n\n)
const lines = buffer.split("\n\n");
buffer = lines.pop(); // Guardamos el fragmento incompleto
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed.startsWith("data: ")) continue;
const payload = trimmed.replace("data: ", "");
if (payload === "[DONE]") {
console.log("Stream completado exitosamente.");
return;
}
try {
const parsed = JSON.parse(payload);
const chunkText = parsed.choices?.[0]?.delta?.content || "";
outputElement.textContent += chunkText;
} catch (e) {
console.warn("Línea SSE no interpretable:", payload);
}
}
}
} catch (err) {
outputElement.textContent = `Error: ${err.message}`;
}
}
Mini-Quiz de Retención
Comprueba tu comprensión antes de pasar a la siguiente lección¿Cuál es la principal ventaja de utilizar Server-Sent Events (SSE) frente a peticiones AJAX tradicionales al integrar un LLM en la web?
¿Tienes dudas con este tema?
Sócrates AI puede darte analogías y explicarte este código paso a paso.🚀 ¿Quieres dominar IA Aplicada a Desarrollo Web: APIs, RAG & Agentes y crear proyectos reales?
Aprende arquitectura limpia, desarrollo web moderno, buenas prácticas y despliegue en producción con nuestro Bootcamp Fullstack Developer con mentorías en vivo.
🏛️ Autoría y Propiedad Intelectual: Obra educativa original de David Amador para Kilopolis Academia (Solucionáticos), estructurada sobre las especificaciones y estándares abiertos del W3C, el estándar vivo de WHATWG y la documentación oficial de código abierto. © Todos los derechos reservados.