6.4 KiB
6.4 KiB
🔧 Guía de Solución de Errores SSE
Error: "❌ Error en SSE" sin detalles
Diagnóstico Rápido
-
Revisar la consola del navegador
- Buscar el nuevo log con
readyState: X (STATE_NAME) - Estados posibles:
0 (CONNECTING): El navegador está intentando conectar1 (OPEN): Conexión establecida correctamente2 (CLOSED): Conexión cerrada (error)
- Buscar el nuevo log con
-
Verificar la pestaña Network
- Buscar la petición a
sse_events.php - Ver el status code:
200: OK (pero puede haber error en el stream)401: No autenticado500: Error del servidor502/504: Error de proxy/timeout
- Buscar la petición a
Solución por Estado
Estado CLOSED (readyState: 2)
Causa común: El servidor cierra la conexión inmediatamente
Solución:
# 1. Verificar logs del servidor
tail -f /var/log/apache2/error.log
# o
tail -f /var/log/nginx/error.log
# 2. Probar el endpoint directamente
curl -N http://localhost:8000/api/sse_events.php?token=demo_token
# 3. Ejecutar el diagnóstico completo
php test_sse_complete.php
Posibles problemas:
- PHP cierra la conexión por timeout → Verificar
set_time_limit(0)en sse_events.php - Buffer de salida activo → Verificar que no hay
ob_start()antes - Nginx/Apache cortando la conexión → Configurar proxy buffering off
Estado CONNECTING (readyState: 0)
Causa común: El navegador no puede conectar al servidor
Solución:
# 1. Verificar que el servidor está corriendo
lsof -i :8000
# 2. Verificar firewall
# macOS
sudo pfctl -s rules
# 3. Probar desde curl
curl -I http://localhost:8000/api/sse_events.php?token=demo_token
Configuración del Servidor
Apache (.htaccess)
# Deshabilitar compresión para SSE
<IfModule mod_headers.c>
<FilesMatch "sse_events\.php$">
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set X-Accel-Buffering "no"
SetEnv no-gzip 1
</FilesMatch>
</IfModule>
Nginx (nginx.conf)
location /api/sse_events.php {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
include fastcgi_params;
# Deshabilitar buffering para SSE
fastcgi_buffering off;
proxy_buffering off;
# Timeouts largos
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
}
PHP-FPM (www.conf)
; Aumentar timeout de ejecución
request_terminate_timeout = 300s
; Permitir más procesos para SSE
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
Pruebas Manuales
Test 1: Verificar headers
curl -I http://localhost:8000/api/sse_events.php?token=demo_token
Esperado:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache, no-store, must-revalidate
Connection: keep-alive
X-Accel-Buffering: no
Test 2: Recibir eventos
curl -N http://localhost:8000/api/sse_events.php?token=demo_token
Esperado:
event: connected
data: {"timestamp":1706300000,"user_id":"token_12345678","mode":"authenticated"}
: heartbeat
Test 3: Diagnóstico completo
php test_sse_complete.php
Esperado:
✅ Headers SSE correctos
[1] 📨 Evento: connected
📦 Data: {
"timestamp": 1706300000,
"user_id": "token_12345678",
"mode": "authenticated"
}
Solución de Problemas Comunes
Error: "net::ERR_INCOMPLETE_CHUNKED_ENCODING"
Causa: El servidor termina el stream abruptamente
Solución:
- Verificar que no hay errores PHP en el stream
- Aumentar
max_execution_timeen php.ini - Verificar que no hay
exit()odie()en el loop SSE
Error: "Failed to fetch"
Causa: CORS o credenciales
Solución:
// En conversations.php, verificar que se usa:
this.eventSource = new EventSource(sseUrl, {
withCredentials: true
});
// En sse_events.php, agregar headers CORS:
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Credentials: true');
Error: Connection timeout después de 30s
Causa: Servidor proxy cortando conexión
Solución Apache:
Timeout 300
KeepAliveTimeout 300
Solución Nginx:
proxy_read_timeout 300s;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
Debugging Avanzado
Habilitar logs detallados PHP
// Agregar al inicio de sse_events.php
error_reporting(E_ALL);
ini_set('display_errors', 0); // No mostrar en stream
ini_set('log_errors', 1);
ini_set('error_log', '/tmp/sse_debug.log');
Monitorear eventos en tiempo real
# Terminal 1: Ver logs
tail -f /tmp/sse_debug.log
# Terminal 2: Conectar SSE
php test_sse_complete.php
# Terminal 3: Enviar evento de prueba
curl -X POST http://localhost:8000/api/push_event.php \
-H "Content-Type: application/json" \
-d '{"event":"test","data":{"message":"Prueba"},"target":"all"}'
Checklist de Verificación
- El servidor está corriendo en el puerto esperado
- Los headers SSE están correctos (Content-Type: text/event-stream)
- No hay buffering de salida activo
- El endpoint responde con HTTP 200
- Se recibe el evento 'connected' al conectar
- Los eventos tienen el formato correcto (event: XXX\ndata: {}\n\n)
- El archivo de eventos temporal es escribible (/uploads/)
- Los logs no muestran errores PHP
- El navegador no está bloqueando la conexión (CORS)
- La autenticación está funcionando (sesión o token)
Contacto y Soporte
Si después de seguir esta guía el problema persiste:
- Ejecutar
php test_sse_complete.phpy copiar la salida completa - Verificar
/tmp/sse_debug.logy copiar los últimos 50 líneas - Revisar la consola del navegador y copiar todos los logs relacionados con SSE
- Verificar Network tab y copiar headers/response de sse_events.php
Mejoras Implementadas
1. Mejor Logging en Cliente (conversations.php)
- ✅ Log detallado del readyState con nombre del estado
- ✅ Limpieza de timeout antes de reconectar
- ✅ Try-catch al cerrar EventSource
2. Mejor Manejo en Servidor (sse_events.php)
- ✅ Límite de tiempo de conexión (5 minutos)
- ✅ Detección de cliente desconectado
- ✅ Logs más detallados con trace completo
- ✅ Headers optimizados para diferentes servidores
3. Herramientas de Diagnóstico
- ✅ test_sse_complete.php: Prueba completa de conexión
- ✅ Parseo de eventos en tiempo real
- ✅ Medición de tiempos de conexión