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.
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 | Sí | A veces |
| Complejidad | Simple | Compleja |
| Datos Binarios | No (solo texto) | Sí |
| 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:
- Cambios de estado de mascotas (disponible → adoptada)
- Notificaciones de pedidos (realizado, enviado, entregado)
- Actualizaciones de inventario
- Cambios de precios
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:
- Pujas en subastas en vivo
- Chat en tiempo real con soporte
- Planificación colaborativa del cuidado de mascotas
- Actualizaciones de inventario en vivo durante las ventas
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:
- Verificar tipos de eventos
- Validar cargas útiles JSON
- Probar el comportamiento de reconexión
- Verificar IDs de eventos
3. Escenarios de prueba:
- Caídas de conexión
- Reinicios del servidor
- Orden de eventos
- Reanudar desde el último evento
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:
- Verificar formatos de mensajes
- Probar el flujo bidireccional
- Verificar el manejo de la conexión
- Probar escenarios de error
4. Escenarios de prueba:
- Múltiples conexiones concurrentes
- Orden de mensajes
- Tiempos de espera de conexión
- Lógica de reconexión
Cuándo Usar Cada Uno
Use SSE Cuando:
- Actualizaciones unidireccionales - El servidor envía al cliente, el cliente no necesita enviar de vuelta
- Configuración simple - Quiera usar infraestructura HTTP estándar
- Reconexión automática - No quiera implementar lógica de reintento
- Compatible con proxies - Necesite funcionar a través de firewalls corporativos
- Notificaciones - Actualizaciones de estado, alertas, feeds en vivo
Ejemplos:
- Notificaciones de adopción de mascotas
- Actualizaciones de estado de pedidos
- Cambios de inventario
- Alertas de precios
- Feeds de noticias
Use WebSocket Cuando:
- Bidireccional - Tanto el cliente como el servidor envían mensajes con frecuencia
- Latencia baja crítica - Juegos, colaboración en tiempo real
- Datos binarios - Envío de imágenes, audio, video
- Protocolo personalizado - Necesite control total sobre el formato del mensaje
- Alta frecuencia de mensajes - Cientos de mensajes por segundo
Ejemplos:
- Pujas en subastas en vivo
- Chat en tiempo real
- Juegos multijugador
- Edición colaborativa
- Transmisión de video en vivo
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.
