Revert "up"

This reverts commit 269dc6bed1.
This commit is contained in:
Lizandro Guarnizo
2026-01-27 01:04:32 -05:00
parent 269dc6bed1
commit 83132ff0d5
3 changed files with 0 additions and 176 deletions
-113
View File
@@ -1,113 +0,0 @@
<?php
/**
* SSE endpoint: stream events for a specific user's conversation
* - Usage: /api/stream_user_messages.php?user_id=3180&since=YYYY-MM-DD%20HH:MM:SS
* - Security: requires session authentication (requireAuthentication)
* - Behavior: tries to use Redis pub/sub if available, otherwise polls DB every 2s for new messages.
*/
require_once __DIR__ . '/../config/config.php';
requireAuthentication();
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
// Tell proxies not to buffer
if (function_exists('apache_setenv')) @apache_setenv('no-gzip', '1');
try {
$userId = intval($_GET['user_id'] ?? 0);
if (!$userId) {
http_response_code(400);
echo "data: {\"error\": \"user_id es requerido\"}\n\n";
exit;
}
ignore_user_abort(true);
set_time_limit(0);
$db = Database::getInstance();
// initialize last_ts: if client passed since, use it; else use latest message timestamp or now-1s
$last = !empty($_GET['since']) ? $_GET['since'] : null;
if (is_null($last)) {
try {
// Database wrapper exposes fetch() for a single row
$r = $db->fetch('SELECT created_at FROM conversations WHERE user_id = :uid ORDER BY created_at DESC LIMIT 1', ['uid' => $userId]);
$last = $r && isset($r['created_at']) ? $r['created_at'] : date('Y-m-d H:i:s', time() - 1);
} catch (Exception $e) {
$last = date('Y-m-d H:i:s', time() - 1);
}
}
// Try Redis pub/sub first (if available)
$usedRedis = false;
if (extension_loaded('redis')) {
try {
$redis = new Redis();
// connect using defaults; expect redis on localhost:6379
$redis->connect('127.0.0.1');
// subscribe in a non-blocking manner via pub/sub loop
$chan = "user_{$userId}";
// Use raw subscribe loop with callback
$usedRedis = true;
$redis->subscribe([$chan], function ($redis, $chanName, $msg) use (&$last) {
// msg expected JSON string with {type:'new_message', user_id, message_id, created_at}
$payload = $msg;
if (is_array($msg)) $payload = json_encode($msg);
echo "event: new_message\n";
echo "data: {$payload}\n\n";
@ob_flush(); @flush();
});
} catch (Exception $e) {
error_log('stream_user_messages.php - redis subscribe failed: ' . $e->getMessage());
$usedRedis = false;
}
}
// Fallback: polling loop (also used if redis is not available or subscription ended)
$start = time();
$timeout = 55; // keep connection alive for ~55s (EventSource will reconnect)
while (!connection_aborted()) {
// Query for messages strictly newer than last timestamp
try {
$rows = $db->fetchAll(
'SELECT id, created_at FROM conversations WHERE user_id = :uid AND created_at > :since ORDER BY created_at ASC',
['uid' => $userId, 'since' => $last]
);
} catch (Exception $e) {
error_log('stream_user_messages.php - DB poll failed: ' . $e->getMessage());
$rows = [];
}
if (!empty($rows)) {
foreach ($rows as $r) {
$d = json_encode(['type' => 'new_message', 'user_id' => $userId, 'message_id' => (int)$r['id'], 'created_at' => $r['created_at']]);
echo "event: new_message\n";
echo "data: {$d}\n\n";
@ob_flush(); @flush();
$last = $r['created_at'];
}
}
// Periodic ping to keep connection alive
echo "event: ping\n";
echo "data: {\"now\": \"" . date('Y-m-d H:i:s') . "\"}\n\n";
@ob_flush(); @flush();
// Break/refresh connection after timeout so client reconnects (avoids very long running PHP requests)
if ((time() - $start) > $timeout) break;
sleep(2);
}
// Final flush
echo "event: close\n";
echo "data: {}\n\n";
@ob_flush(); @flush();
exit;
} catch (Exception $e) {
error_log('stream_user_messages.php - fatal: ' . $e->getMessage());
http_response_code(500);
echo "data: {\"error\": \"Internal server error\"}\n\n";
exit;
}
-12
View File
@@ -304,18 +304,6 @@ class WhatsAppWebhook {
} catch (Exception $e) {
error_log('Failed to create notification: ' . $e->getMessage());
}
// Try to publish a lightweight event to Redis so SSE/WebSocket listeners can be notified immediately
try {
if (extension_loaded('redis')) {
$payload = json_encode(['type' => 'new_message', 'user_id' => $user['id'], 'message_id' => (int)$conversationId, 'created_at' => date('Y-m-d H:i:s')]);
$r = new Redis();
$r->connect('127.0.0.1');
$r->publish('user_' . $user['id'], $payload);
}
} catch (Exception $e) {
error_log('[webhook] redis publish failed: ' . $e->getMessage());
}
// Procesar con bot (protección contra excepciones externas)
try {
-51
View File
@@ -1034,8 +1034,6 @@
this._stagedMessages = [];
// Last message timestamp seen (for delta polling)
this._latestMessage = null;
// SSE connection handle for server push (EventSource)
this._sse = null;
// Removed: automatic "Nuevos mensajes" indicator — we always reload full conversation now
// this._lastRenderMessageCount = 0;
@@ -1900,50 +1898,6 @@
}, 10000);
}
// SSE: start listening for server-sent events for the current conversation
startSSE(userId) {
try {
this.stopSSE();
if (!userId || typeof EventSource === 'undefined') return;
const url = `api/stream_user_messages.php?user_id=${userId}`;
try {
this._sse = new EventSource(url);
this._sse.onmessage = (ev) => {
try {
const d = JSON.parse(ev.data || '{}');
if (d && d.type === 'new_message' && d.user_id == this.currentUserId) {
if (console && console.debug) console.debug('SSE new_message received for user', d.user_id, '-> triggering full load');
if (!this._fullLoadInProgress) {
this.loadMessages(this.currentUserId, true, true).catch(e => console.warn('SSE triggered load failed', e));
} else {
if (console && console.debug) console.debug('SSE: full load already in progress, skipping immediate load');
}
}
} catch (e) { console.warn('SSE message parse failed', e); }
};
this._sse.addEventListener('ping', () => {/* no-op */});
this._sse.onerror = (err) => {
console.warn('SSE error', err);
// Close and attempt reconnect after short delay
try { this._sse.close(); } catch(e) {}
this._sse = null;
setTimeout(() => { if (this.currentUserId == userId) this.startSSE(userId); }, 3000);
};
if (console && console.debug) console.debug('SSE started for user', userId);
} catch (e) { console.warn('Failed to start EventSource', e); }
} catch (e) { console.warn('startSSE failed', e); }
}
stopSSE() {
try {
if (this._sse) {
try { this._sse.close(); } catch(e) {}
this._sse = null;
if (console && console.debug) console.debug('SSE stopped');
}
} catch (e) { /* ignore */ }
}
// New: periodic delta poller to fetch only messages newer than last seen timestamp
async pollNewMessages() {
if (!this.currentUserId) return;
@@ -2303,8 +2257,6 @@
async openConversation(userId, userName, phoneNumber) {
this.currentUserId = userId;
// Stop any previous SSE connection before opening a new conversation
try { this.stopSSE(); } catch(e) { /* ignore */ }
// Clear any staged messages from a previous conversation and hide indicator
try { if (this._stagedMessageIds) { this._stagedMessageIds.clear(); this._stagedCount = 0; this.hideNewMessagesIndicator(); } } catch(e) {}
@@ -2640,9 +2592,6 @@
// Resume auto-refresh after the load
try { this._suspendAutoRefresh = false; } catch(e) {}
// Start SSE connection for this conversation to receive server push events
try { this.startSSE(userId); } catch(e) { console.warn('startSSE failed to initialize', e); }
// Añadir listener para scroll arriba (cargar más historial)
const chatContainer = document.getElementById('chat-conversations');
if (chatContainer) {