WebSocket vs Server-Sent Events: ¿Cuál es Mejor para APIs en Tiempo Real?

Ashley Innocent

Ashley Innocent

13 March 2026

WebSocket vs Server-Sent Events: ¿Cuál es Mejor para APIs en Tiempo Real?

Apidog para empresas

Despliegue local

SSO & RBAC

Conforme con SOC 2

Explorar Apidog Enterprise

TL;DR

Utilice Eventos Enviados por el Servidor (SSE) para actualizaciones unidireccionales de servidor a cliente, como notificaciones y feeds en vivo. Utilice WebSocket para comunicación bidireccional, como chats y juegos. SSE es más simple y funciona sobre HTTP. WebSocket es más complejo pero soporta mensajería bidireccional. La PetstoreAPI Moderna implementa ambos para diferentes casos de uso en tiempo real.

Introducción

Necesita actualizaciones en tiempo real en su API. El estado de una mascota cambia de "disponible" a "adoptada" —los clientes necesitan saberlo inmediatamente. ¿Debe usar WebSocket o Eventos Enviados por el Servidor (SSE)?

La mayoría de los desarrolladores optan por WebSocket porque es "más potente". Pero SSE es a menudo la mejor opción. Es más simple, funciona sobre HTTP estándar y maneja la reconexión automáticamente. WebSocket añade una complejidad que quizás no necesite.

Modern PetstoreAPI implementa ambos protocolos. SSE para actualizaciones de estado de mascotas y notificaciones de pedidos. WebSocket para pujas en subastas en vivo y chat en tiempo real. Cada protocolo sirve para diferentes casos de uso.

💡
Si está construyendo o probando APIs en tiempo real, Apidog soporta pruebas tanto de SSE como de WebSocket. Puede probar flujos de eventos, validar formatos de mensajes y simular escenarios de reconexión.
botón

En esta guía, aprenderá las diferencias entre SSE y WebSocket, verá ejemplos reales de Modern PetstoreAPI y descubrirá cuándo usar cada protocolo.

¿Qué son los Eventos Enviados por el Servidor (SSE)?

SSE es un protocolo basado en HTTP para transmitir eventos del servidor al cliente.

Cómo Funcionan los SSE

El cliente abre una conexión y recibe eventos a medida que ocurren:

const eventSource = new EventSource('https://petstoreapi.com/v1/pets/notifications');

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Actualización de mascota:', data);
};

eventSource.addEventListener('adoption', (event) => {
  const data = JSON.parse(event.data);
  console.log('Mascota adoptada:', data.petId);
});

El servidor envía eventos:

GET /v1/pets/notifications
Accept: text/event-stream

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache

event: adoption
data: {"petId":"019b4132","userId":"user-456"}

event: status-change
data: {"petId":"019b4127","status":"AVAILABLE"}

Características de SSE

1. Comunicación unidireccional

El servidor envía información al cliente. El cliente no puede enviar mensajes de vuelta a través de la conexión SSE (pero puede usar solicitudes HTTP regulares).

2. Construido sobre HTTP

Utiliza HTTP estándar. Funciona a través de proxies, firewalls y CDNs.

3. Reconexión automática

Si la conexión se cae, el navegador se reconecta automáticamente.

4. IDs de eventos para reanudar

El servidor puede enviar IDs de eventos. El cliente reanuda desde el último evento recibido:

id: 123
event: adoption
data: {"petId":"019b4132"}

id: 124
event: status-change
data: {"petId":"019b4127"}

Si se desconecta, el cliente envía la cabecera Last-Event-ID: 124 para reanudar.

5. Protocolo simple

Formato basado en texto. Fácil de depurar con curl:

curl -N -H "Accept: text/event-stream" \
  https://petstoreapi.com/v1/pets/notifications

Limitaciones de SSE

1. Solo unidireccional

El cliente no puede enviar mensajes a través de SSE. Se necesitan solicitudes HTTP separadas para la comunicación cliente-servidor.

2. Solo texto

SSE envía texto. Los datos binarios deben codificarse en base64.

3. Límites de conexión del navegador

Los navegadores limitan las conexiones SSE por dominio (normalmente 6). Esto no suele ser un problema para la mayoría de las aplicaciones.

4. Sin compresión incorporada

La compresión HTTP funciona, pero no hay compresión a nivel de protocolo como en WebSocket.

¿Qué es WebSocket?

WebSocket es un protocolo bidireccional full-duplex sobre una conexión persistente.

Cómo Funciona WebSocket

Tanto el cliente como el servidor pueden enviar mensajes en cualquier momento:

const ws = new WebSocket('wss://petstoreapi.com/auctions/019b4132');

// Send message to server
ws.send(JSON.stringify({
  type: 'bid',
  amount: 500
}));

// Receive messages from server
ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Actualización de subasta:', data);
};

ws.onclose = () => {
  console.log('Conexión cerrada');
  // Se necesita lógica de reconexión manual
};

El servidor puede enviar en cualquier momento:

{"type":"bid","userId":"user-456","amount":550}
{"type":"outbid","newAmount":550}

El cliente puede enviar en cualquier momento:

{"type":"bid","amount":600}
{"type":"watch","petId":"019b4132"}

Características de WebSocket

1. Bidireccional

Tanto el cliente como el servidor pueden enviar mensajes en cualquier momento. Verdadera comunicación bidireccional.

2. Baja latencia

Conexión persistente. Sin sobrecarga HTTP por mensaje. Ideal para juegos, chat, colaboración en vivo.

3. Soporte binario

Puede enviar datos binarios directamente. No se necesita codificación base64.

4. Protocolo personalizado

Utiliza ws:// o wss:// (seguro). No es HTTP después del handshake inicial.

5. Basado en tramas

Los mensajes están enmarcados (framed). Puede enviar mensajes parciales y reensamblarlos.

Limitaciones de WebSocket

1. Configuración compleja

Requiere un servidor WebSocket. Más complejo que los endpoints HTTP.

2. Reconexión manual

Sin reconexión automática. Debe implementar la lógica de reintento.

3. Problemas con proxies

Algunos proxies corporativos bloquean WebSocket. Los proxies HTTP no entienden ws://.

4. Con estado (Stateful)

El servidor debe rastrear las conexiones. Más difícil de escalar que HTTP sin estado (stateless).

5. Sin características HTTP

No se pueden usar el almacenamiento en caché HTTP, los códigos de estado o las cabeceras estándar después del handshake.

Comparación lado a lado

Característica SSE WebSocket
Dirección Servidor → Cliente Bidireccional
Protocolo HTTP Personalizado (ws://)
Reconexión Automática Manual
Soporte de Navegador Todos los modernos Todos los modernos
Compatible con Proxy A veces
Complejidad Simple Compleja
Datos Binarios No (solo texto)
Latencia Baja Muy baja
Escalabilidad Alta (sin estado) Media (con estado)
Caso de Uso Notificaciones, feeds Chat, juegos, colaboración

Cómo Modern PetstoreAPI Usa Ambos

Modern PetstoreAPI implementa tanto SSE como WebSocket para diferentes escenarios.

SSE para Actualizaciones de Mascotas

Endpoint: GET /v1/pets/notifications

const events = new EventSource(
  'https://petstoreapi.com/v1/pets/notifications?userId=user-456'
);

events.addEventListener('adoption', (e) => {
  const data = JSON.parse(e.data);
  showNotification(`${data.petName} fue adoptado!`);
});

events.addEventListener('status-change', (e) => {
  const data = JSON.parse(e.data);
  updatePetStatus(data.petId, data.status);
});

Implementación del servidor:

app.get('/v1/pets/notifications', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  const userId = req.query.userId;

  // Suscribirse a las actualizaciones de mascotas
  const subscription = petUpdates.subscribe(userId, (event) => {
    res.write(`event: ${event.type}\n`);
    res.write(`data: ${JSON.stringify(event.data)}\n\n`);
  });

  req.on('close', () => {
    subscription.unsubscribe();
  });
});

Casos de uso:

WebSocket para Subastas en Vivo

Endpoint: wss://petstoreapi.com/auctions/{auctionId}

const ws = new WebSocket('wss://petstoreapi.com/auctions/019b4132');

// Realizar puja
function placeBid(amount) {
  ws.send(JSON.stringify({
    type: 'bid',
    amount
  }));
}

// Recibir actualizaciones
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  switch (msg.type) {
    case 'bid':
      updateCurrentBid(msg.amount, msg.userId);
      break;
    case 'outbid':
      showOutbidNotification(msg.newAmount);
      break;
    case 'auction-end':
      showAuctionResult(msg.winner);
      break;
  }
};

Implementación del servidor:

wss.on('connection', (ws, req) => {
  const auctionId = req.params.auctionId;
  const auction = auctions.get(auctionId);

  ws.on('message', (data) => {
    const msg = JSON.parse(data);

    if (msg.type === 'bid') {
      const result = auction.placeBid(msg.userId, msg.amount);

      // Transmitir a todos los participantes
      auction.participants.forEach(participant => {
        participant.send(JSON.stringify({
          type: 'bid',
          userId: msg.userId,
          amount: msg.amount
        }));
      });
    }
  });
});

Casos de uso:

Probando APIs en Tiempo Real con Apidog

Apidog soporta la prueba de APIs tanto SSE como WebSocket.

Probando SSE

1. Crear solicitud SSE:

GET https://petstoreapi.com/v1/pets/notifications
Accept: text/event-stream

2. Validar eventos:

3. Escenarios de prueba:

Probando WebSocket

1. Crear conexión WebSocket:

wss://petstoreapi.com/auctions/019b4132

2. Enviar mensajes de prueba:

{"type":"bid","amount":500}
{"type":"watch","petId":"019b4132"}

3. Validar respuestas:

4. Escenarios de prueba:

Cuándo Usar Cada Uno

Use SSE Cuando:

Ejemplos:

Use WebSocket Cuando:

Ejemplos:

No Use WebSocket Solo Porque:

❌ “Es más avanzado” - Complejidad sin beneficio

❌ “Todo el mundo lo usa” - SSE es a menudo más simple

❌ “Es más rápido” - SSE es lo suficientemente rápido para la mayoría de los casos de uso

❌ “Es bidireccional” - ¿Realmente necesita bidireccionalidad?

Conclusión

Tanto SSE como WebSocket permiten la comunicación en tiempo real, pero están diseñados para escenarios diferentes. SSE destaca en las actualizaciones unidireccionales de servidor a cliente con reconexión automática y compatibilidad HTTP. WebSocket brilla en la comunicación bidireccional de baja latencia.

Modern PetstoreAPI muestra cómo usar ambos protocolos de manera efectiva. SSE para notificaciones y actualizaciones de estado. WebSocket para subastas en vivo y chat. Elija según su caso de uso, no según qué protocolo parezca "mejor".

Pruebe sus APIs en tiempo real con Apidog para asegurarse de que tanto las implementaciones de SSE como las de WebSocket funcionen correctamente en diferentes escenarios.

Preguntas Frecuentes

¿Puede SSE funcionar a través de firewalls corporativos?

Sí. SSE utiliza HTTP estándar, por lo que funciona a través de proxies y firewalls HTTP. WebSocket utiliza un protocolo personalizado que algunos proxies bloquean.

¿Es WebSocket más rápido que SSE?

WebSocket tiene una latencia ligeramente menor (sin sobrecarga HTTP por mensaje), pero para la mayoría de las aplicaciones, la diferencia es insignificante. SSE es lo suficientemente rápido para notificaciones, feeds y actualizaciones de estado.

¿Cómo se maneja la reconexión de SSE?

El navegador maneja la reconexión automáticamente. Envíe IDs de eventos desde el servidor, y el cliente reanudará desde el último evento recibido utilizando la cabecera Last-Event-ID.

¿Se puede usar SSE con aplicaciones móviles?

Sí. iOS y Android soportan SSE a través de clientes HTTP nativos o librerías. SSE funciona dondequiera que funcione HTTP.

¿Cuál es el tiempo máximo de conexión SSE?

No hay un límite estricto. Las conexiones SSE pueden permanecer abiertas indefinidamente. Algunos proxies o balanceadores de carga pueden tener tiempos de espera (típicamente 30-60 segundos), pero el navegador se reconectará automáticamente.

¿Puede WebSocket enviar datos binarios?

Sí. WebSocket soporta tanto tramas de texto como binarias. Puede enviar imágenes, audio o cualquier dato binario sin codificación base64.

¿Cuántas conexiones SSE puede tener un navegador?

Los navegadores limitan las conexiones SSE por dominio (típicamente 6). Esto rara vez es un problema; la mayoría de las aplicaciones solo necesitan 1-2 conexiones SSE.

¿Necesita un servidor especial para SSE?

No. Cualquier servidor HTTP puede manejar SSE. Simplemente configure las cabeceras correctas (Content-Type: text/event-stream) y mantenga la conexión abierta.

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs