Files
whatsapp/GUIA_SOLUCION_SSE.md
T
2026-01-27 14:51:41 -05:00

6.4 KiB

🔧 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:

# 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:

  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:

// 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:

  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