From 7b8a4c20569a88fa6047a790f5341a177dde3c8a Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Fri, 19 Jun 2026 21:47:24 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20SSE=20libera=20worker=20en=2028s=20y=20d?= =?UTF-8?q?etecta=20desconexi=C3=B3n=20cada=20200ms?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TTL de 28s por conexión; EventSource reconecta automáticamente (retry:3000) - Reemplaza sleep(2) por loop usleep(200ms) para detectar pagehide rápido - PHP-FPM workers aumentados de 5 → 20 (directo en servidor) Co-Authored-By: Claude Sonnet 4.6 --- admin/DashboardController.php | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/admin/DashboardController.php b/admin/DashboardController.php index 8697784..817f2a0 100644 --- a/admin/DashboardController.php +++ b/admin/DashboardController.php @@ -202,12 +202,11 @@ HTML; header('X-Accel-Buffering: no'); // disable nginx buffering header('Connection: keep-alive'); - set_time_limit(0); + set_time_limit(35); ignore_user_abort(false); $lastId = max(0, (int)($_GET['after'] ?? 0)); - // Anchor to latest ID if no after param if ($lastId === 0) { try { $row = db()->query('SELECT id FROM webhook_logs ORDER BY id DESC LIMIT 1')->fetch(); @@ -215,7 +214,13 @@ HTML; } catch (\PDOException $e) {} } - while (!connection_aborted()) { + // Tell the client to reconnect after 3s if connection drops + echo "retry: 3000\n\n"; + ob_flush(); flush(); + + $deadline = time() + 28; // release worker after 28s, client auto-reconnects + + while (!connection_aborted() && time() < $deadline) { try { $stmt = db()->prepare( 'SELECT id, event_field, from_number, contact_name, @@ -229,7 +234,7 @@ HTML; $lastId = (int)end($rows)['id']; echo 'data: ' . json_encode($rows, JSON_UNESCAPED_UNICODE) . "\n\n"; } else { - echo ": heartbeat\n\n"; // keep connection alive + echo ": heartbeat\n\n"; } } catch (\PDOException $e) { echo ": db-error\n\n"; @@ -237,7 +242,11 @@ HTML; ob_flush(); flush(); - sleep(2); + + // Sleep in 200ms chunks so connection_aborted() is checked frequently + for ($i = 0; $i < 10 && !connection_aborted(); $i++) { + usleep(200000); + } } exit; }