up
This commit is contained in:
@@ -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!** 🚀
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user