# 🔧 Guía de Solución de Errores SSE ## Error: "❌ Error en SSE" sin detalles ### Diagnóstico Rápido 1. **Revisar la consola del navegador** - Buscar el nuevo log con `readyState: X (STATE_NAME)` - Estados posibles: - `0 (CONNECTING)`: El navegador está intentando conectar - `1 (OPEN)`: Conexión establecida correctamente - `2 (CLOSED)`: Conexión cerrada (error) 2. **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 autenticado - `500`: Error del servidor - `502/504`: Error de proxy/timeout ### Solución por Estado #### Estado CLOSED (readyState: 2) **Causa común**: El servidor cierra la conexión inmediatamente **Solución**: ```bash # 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**: ```bash # 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) ```apache # Deshabilitar compresión para SSE Header set Cache-Control "no-cache, no-store, must-revalidate" Header set X-Accel-Buffering "no" SetEnv no-gzip 1 ``` #### Nginx (nginx.conf) ```nginx 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) ```ini ; 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 ```bash 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 ```bash 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 ```bash 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**: 1. Verificar que no hay errores PHP en el stream 2. Aumentar `max_execution_time` en php.ini 3. Verificar que no hay `exit()` o `die()` en el loop SSE #### Error: "Failed to fetch" **Causa**: CORS o credenciales **Solución**: ```javascript // En conversations.php, verificar que se usa: this.eventSource = new EventSource(sseUrl, { withCredentials: true }); ``` ```php // 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**: ```apache Timeout 300 KeepAliveTimeout 300 ``` **Solución Nginx**: ```nginx proxy_read_timeout 300s; proxy_connect_timeout 300s; proxy_send_timeout 300s; ``` ### Debugging Avanzado #### Habilitar logs detallados PHP ```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 ```bash # 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: 1. Ejecutar `php test_sse_complete.php` y copiar la salida completa 2. Verificar `/tmp/sse_debug.log` y copiar los últimos 50 líneas 3. Revisar la consola del navegador y copiar todos los logs relacionados con SSE 4. 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