This commit is contained in:
Lizandro Guarnizo
2026-01-27 15:04:51 -05:00
parent 6e3f375f91
commit 56c6a24fa5
4 changed files with 463 additions and 3 deletions
+270
View File
@@ -0,0 +1,270 @@
# 🚀 Configuración SSE para HestiaCP
## ✅ Pasos para Activar SSE en tu Servidor HestiaCP
### 1. Verificar que el código esté en el servidor
```bash
# Subir por FTP/SFTP o Git
cd /home/tu-usuario/web/tu-dominio.com/public_html/
ls -la api/sse_events.php # Debe existir
```
### 2. Configurar Apache para SSE (si usas Apache)
**Opción A: Editar .htaccess en la raíz**
```apache
# Agregar al final de .htaccess
<IfModule mod_headers.c>
# SSE Headers
<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>
```
**Opción B: Crear .htaccess específico en /api/**
```bash
cd /home/tu-usuario/web/tu-dominio.com/public_html/api/
nano .htaccess
```
Contenido:
```apache
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set X-Accel-Buffering "no"
SetEnv no-gzip 1
</IfModule>
# Prevenir timeout en SSE
<IfModule mod_fcgid.c>
FcgidIOTimeout 300
</IfModule>
```
### 3. Ajustar PHP-FPM (Recomendado)
Editar configuración PHP-FPM en HestiaCP:
1. **Panel HestiaCP****Web****tu dominio****Edit**
2. **Backend Template**: PHP-FPM
3. **PHP Version**: 8.x
Luego editar el archivo de configuración (vía SSH):
```bash
# Ubicación típica en HestiaCP
sudo nano /etc/php/8.2/fpm/pool.d/tu-usuario.conf
# Agregar o modificar:
request_terminate_timeout = 300s
pm.max_requests = 500
```
Reiniciar PHP-FPM:
```bash
sudo systemctl restart php8.2-fpm
```
### 4. Verificar Nginx (si usas Nginx)
Si tu dominio usa Nginx como proxy, editar la configuración:
```bash
sudo nano /etc/nginx/conf.d/domains/tu-dominio.com.conf
```
Agregar dentro del bloque `location ~ \.php$`:
```nginx
# Configuración especial para SSE
location ~ ^/api/sse_events\.php$ {
fastcgi_buffering off;
proxy_buffering off;
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
include fastcgi_params;
}
```
Reiniciar Nginx:
```bash
sudo systemctl restart nginx
```
### 5. Probar SSE desde el servidor
```bash
# Conectar por SSH a tu servidor
ssh usuario@tu-dominio.com
# Probar SSE
curl -N -m 5 'https://tu-dominio.com/api/sse_events.php?token=demo_token'
```
**Respuesta esperada:**
```
event: connected
data: {"timestamp":1706300000,"user_id":"token_12345678","mode":"authenticated","status":"ready"}
: heartbeat
```
Si ves esto, **SSE está funcionando**
### 6. Probar desde el navegador
1. Abrir tu sitio: `https://tu-dominio.com/conversations.php`
2. Abrir Consola del navegador (F12 → Console)
3. Buscar:
```
Conectando a SSE para eventos en tiempo real...
SSE URL: https://tu-dominio.com/api/sse_events.php?token=...
✅ SSE conectado (🔐 autenticado): {...}
```
### 7. Solución de Problemas
#### Error: "Failed to fetch" o timeout
**Causa**: Firewall o mod_security bloqueando
**Solución**:
```bash
# Desactivar mod_security para SSE (temporal)
sudo a2dismod security2
sudo systemctl restart apache2
# O agregar excepción en .htaccess:
<IfModule mod_security2.c>
SecRuleEngine Off
</IfModule>
```
#### Error: "EventSource's response has a MIME type"
**Causa**: Headers incorrectos
**Solución**: Verificar que sse_events.php tenga:
```php
header('Content-Type: text/event-stream');
```
#### Error: Conexión se cierra cada 30 segundos
**Causa**: Timeout de proxy
**Solución**: Aumentar timeouts en nginx.conf o apache2.conf:
```
# Apache
Timeout 300
KeepAliveTimeout 300
# Nginx
proxy_read_timeout 300s;
```
### 8. Configuración de Seguridad (Producción)
#### A. Token seguro en vez de demo_token
Editar `api/sse_events.php`:
```php
// Generar token en login
$_SESSION['sse_token'] = bin2hex(random_bytes(32));
// Validar token en SSE
$token = $_GET['token'] ?? null;
if ($token && isset($_SESSION['sse_token']) && $token === $_SESSION['sse_token']) {
$authenticated = true;
}
```
En `conversations.php`:
```javascript
// Usar token de sesión
const token = '<?php echo $_SESSION['sse_token'] ?? 'demo_token'; ?>';
const sseUrl = `${baseUrl}/api/sse_events.php?token=${token}&t=${Date.now()}`;
```
#### B. Restringir acceso por IP (opcional)
En `.htaccess`:
```apache
<FilesMatch "sse_events\.php$">
# Solo permitir desde localhost o IPs específicas
Require ip 127.0.0.1
Require ip tu.ip.publica
</FilesMatch>
```
### 9. Monitoreo
Ver conexiones SSE activas:
```bash
# Ver procesos PHP activos
ps aux | grep sse_events
# Ver logs de errores
tail -f /var/log/php8.2-fpm.log
tail -f /var/log/apache2/error.log
tail -f /var/log/nginx/error.log
```
### 10. Performance
Para muchos usuarios simultáneos:
```bash
# Aumentar límites PHP-FPM
sudo nano /etc/php/8.2/fpm/pool.d/tu-usuario.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 500
```
---
## 🎯 Checklist de Verificación
- [ ] Archivo `api/sse_events.php` subido al servidor
- [ ] `.htaccess` configurado con headers SSE
- [ ] PHP-FPM timeout aumentado a 300s
- [ ] Nginx/Apache configurado (si aplica)
- [ ] Test con curl funciona (muestra "event: connected")
- [ ] Test desde navegador funciona (console.log muestra "✅ SSE conectado")
- [ ] Token de seguridad configurado (no usar demo_token en producción)
- [ ] Firewall/mod_security permite conexiones largas
---
## 📞 Soporte HestiaCP
Si tienes problemas:
1. **Panel HestiaCP**: https://tu-dominio.com:8083
2. **Logs**: Panel → Log Files
3. **SSH**: Usuario y contraseña en el panel
4. **Documentación**: https://docs.hestiacp.com/
---
## ✅ Resultado Esperado
Una vez configurado correctamente:
```
ANTES (desarrollo local):
http://localhost:8000/api/sse_events.php
❌ Timeout (servidor PHP built-in no soporta SSE)
AHORA (producción HestiaCP):
https://tu-dominio.com/api/sse_events.php
✅ Conectado - eventos en tiempo real < 1 segundo
```
**¡Tu sistema de notificaciones en tiempo real estará funcionando!** 🚀
+35
View File
@@ -0,0 +1,35 @@
# Configuración SSE para HestiaCP
# Colocar este archivo en: /api/.htaccess
<IfModule mod_headers.c>
# Deshabilitar buffering para SSE
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set X-Accel-Buffering "no"
Header set Connection "keep-alive"
# Permitir CORS si es necesario
# Header set Access-Control-Allow-Origin "*"
# Header set Access-Control-Allow-Credentials "true"
# Deshabilitar compresión
SetEnv no-gzip 1
</IfModule>
# Aumentar timeouts para SSE
<IfModule mod_fcgid.c>
FcgidIOTimeout 300
FcgidConnectTimeout 300
</IfModule>
# Desactivar mod_security para SSE (si causa problemas)
<IfModule mod_security2.c>
SecRuleEngine Off
</IfModule>
# Prevenir que Apache cierre la conexión
RewriteEngine Off
Options -MultiViews
# PHP settings
php_value max_execution_time 300
php_value max_input_time 300
Executable
+153
View File
@@ -0,0 +1,153 @@
#!/bin/bash
# Script de verificación SSE para HestiaCP
# Ejecutar en el servidor: bash check_sse.sh
echo "🔍 Verificación de SSE para HestiaCP"
echo "===================================="
echo ""
# 1. Verificar que el archivo existe
echo "1️⃣ Verificando archivos..."
if [ -f "api/sse_events.php" ]; then
echo " ✅ api/sse_events.php existe"
else
echo " ❌ api/sse_events.php NO encontrado"
echo " → Asegúrate de subir el archivo al servidor"
exit 1
fi
# 2. Verificar permisos
echo ""
echo "2️⃣ Verificando permisos..."
PERMS=$(stat -c "%a" api/sse_events.php 2>/dev/null || stat -f "%A" api/sse_events.php 2>/dev/null)
if [ "$PERMS" -ge "644" ]; then
echo " ✅ Permisos correctos ($PERMS)"
else
echo " ⚠️ Permisos: $PERMS (se recomienda 644)"
echo " Ejecutar: chmod 644 api/sse_events.php"
fi
# 3. Verificar versión PHP
echo ""
echo "3️⃣ Verificando PHP..."
PHP_VERSION=$(php -v | head -n 1)
echo " $PHP_VERSION"
if php -v | grep -q "PHP 8"; then
echo " ✅ PHP 8.x detectado"
elif php -v | grep -q "PHP 7"; then
echo " ⚠️ PHP 7.x (recomendado PHP 8.x)"
else
echo " ❌ Versión PHP desconocida"
fi
# 4. Verificar sintaxis PHP
echo ""
echo "4️⃣ Verificando sintaxis PHP..."
if php -l api/sse_events.php > /dev/null 2>&1; then
echo " ✅ Sin errores de sintaxis"
else
echo " ❌ Error de sintaxis en sse_events.php"
php -l api/sse_events.php
exit 1
fi
# 5. Verificar configuración PHP-FPM
echo ""
echo "5️⃣ Verificando PHP-FPM..."
if systemctl is-active --quiet php8.2-fpm || systemctl is-active --quiet php8.1-fpm || systemctl is-active --quiet php-fpm; then
echo " ✅ PHP-FPM está corriendo"
else
echo " ⚠️ PHP-FPM no detectado o no corriendo"
fi
# 6. Probar conexión SSE local
echo ""
echo "6️⃣ Probando conexión SSE..."
echo " Conectando (3 segundos)..."
RESPONSE=$(timeout 3 curl -N -s 'http://localhost/api/sse_events.php?token=demo_token' 2>&1 || echo "timeout")
if echo "$RESPONSE" | grep -q "event: connected"; then
echo " ✅ SSE funciona correctamente"
echo " Respuesta:"
echo "$RESPONSE" | head -5 | sed 's/^/ /'
elif echo "$RESPONSE" | grep -q "timeout"; then
echo " ⚠️ Timeout - SSE puede no estar configurado correctamente"
echo " → Revisar configuración Apache/Nginx"
elif echo "$RESPONSE" | grep -q "401"; then
echo " ⚠️ HTTP 401 - Problema de autenticación"
echo " → Revisar config/auth.php"
else
echo " ❌ Error inesperado"
echo " Respuesta:"
echo "$RESPONSE" | head -10 | sed 's/^/ /'
fi
# 7. Verificar .htaccess
echo ""
echo "7️⃣ Verificando .htaccess..."
if [ -f "api/.htaccess" ]; then
echo " ✅ api/.htaccess existe"
if grep -q "X-Accel-Buffering" api/.htaccess; then
echo " ✅ Configuración SSE encontrada"
else
echo " ⚠️ Falta configuración SSE en .htaccess"
echo " → Ver GUIA_HESTIA_SSE.md"
fi
else
echo " ⚠️ api/.htaccess no encontrado"
echo " → Crear según GUIA_HESTIA_SSE.md"
fi
# 8. Verificar configuración base de datos
echo ""
echo "8️⃣ Verificando configuración..."
if [ -f "config/config.php" ]; then
echo " ✅ config/config.php existe"
if php -r "require_once 'config/config.php'; echo 'OK';" 2>/dev/null | grep -q "OK"; then
echo " ✅ config.php carga correctamente"
else
echo " ⚠️ Error al cargar config.php"
fi
else
echo " ❌ config/config.php NO encontrado"
exit 1
fi
# 9. Verificar tabla notifications
echo ""
echo "9️⃣ Verificando tabla notifications..."
if php -r "require_once 'config/config.php'; \$db = Database::getInstance(); \$r = \$db->fetchAll('SHOW TABLES LIKE \"notifications\"'); echo (count(\$r) > 0 ? 'OK' : 'NO');" 2>/dev/null | grep -q "OK"; then
echo " ✅ Tabla notifications existe"
else
echo " ⚠️ Tabla notifications no encontrada"
echo " → Ejecutar migration para crear tabla"
fi
# Resumen final
echo ""
echo "===================================="
echo "📊 Resumen"
echo "===================================="
echo ""
if echo "$RESPONSE" | grep -q "event: connected"; then
echo "✅ SSE está funcionando correctamente"
echo ""
echo "Próximos pasos:"
echo "1. Abrir https://tu-dominio.com/conversations.php"
echo "2. Abrir consola del navegador (F12)"
echo "3. Verificar: '✅ SSE conectado'"
echo ""
echo "🚀 Sistema de notificaciones en tiempo real activo!"
else
echo "⚠️ SSE necesita configuración adicional"
echo ""
echo "Próximos pasos:"
echo "1. Revisar GUIA_HESTIA_SSE.md"
echo "2. Configurar .htaccess para SSE"
echo "3. Ajustar PHP-FPM timeout (300s)"
echo "4. Ejecutar: bash check_sse.sh"
fi
echo ""
+5 -3
View File
@@ -1081,9 +1081,11 @@
console.log('Conectando a SSE para eventos en tiempo real...');
try {
// EventSource no soporta withCredentials directamente
// Usar token en URL como alternativa
const sseUrl = 'api/sse_events.php?token=demo_token&t=' + Date.now();
// Detectar URL base automáticamente (funciona en dev y producción)
const baseUrl = window.location.origin; // http://localhost:8000 o https://tu-dominio.com
const sseUrl = `${baseUrl}/api/sse_events.php?token=demo_token&t=${Date.now()}`;
console.log('SSE URL:', sseUrl);
this.eventSource = new EventSource(sseUrl);
// Evento: conexión establecida