mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
fix(web): support multiple gateway tabs by reducing SSE connections
Each browser tab opened 2 SSE connections (chat events + log events). With the HTTP/1.1 per-origin limit of 6, the 3rd tab exhausted the pool and couldn't load any data. Three changes: 1. Lazy log SSE — only connect when the logs tab is active, disconnect when switching away. Most users rarely view logs, so this saves a connection slot per tab. 2. Visibility API — close SSE when the browser tab goes to background (user switches to another tab), reconnect when it becomes visible. Background tabs don't need real-time events. 3. Combined with the existing beforeunload cleanup, this means: - Active foreground tab: 1 connection (chat SSE only, +1 if logs tab) - Background tabs: 0 connections - Closed/refreshed tabs: 0 connections (beforeunload cleanup) This allows many gateway tabs to coexist within the 6-connection limit. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
@@ -184,7 +184,7 @@ function authenticate() {
|
||||
cleaned.searchParams.delete('log_level');
|
||||
window.history.replaceState({}, '', cleaned.pathname + cleaned.search);
|
||||
connectSSE();
|
||||
connectLogSSE();
|
||||
// Log SSE is connected lazily when the logs tab is opened (saves a connection slot).
|
||||
startGatewayStatusPolling();
|
||||
checkTeeStatus();
|
||||
loadThreads();
|
||||
@@ -223,6 +223,20 @@ window.addEventListener('beforeunload', () => {
|
||||
if (logEventSource) { logEventSource.close(); logEventSource = null; }
|
||||
});
|
||||
|
||||
// Pause SSE when the browser tab is hidden (another tab is focused) and resume
|
||||
// when it becomes visible again. This frees connection slots for other tabs
|
||||
// running the gateway — without this, each tab holds 1-2 SSE connections and
|
||||
// the 3rd tab exhausts the browser's per-origin limit.
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.hidden) {
|
||||
if (eventSource) { eventSource.close(); eventSource = null; }
|
||||
if (logEventSource) { logEventSource.close(); logEventSource = null; }
|
||||
} else if (token) {
|
||||
connectSSE();
|
||||
if (currentTab === 'logs') connectLogSSE();
|
||||
}
|
||||
});
|
||||
|
||||
// Note: main event listener registration is at the bottom of this file (search
|
||||
// "Event Listener Registration"). Do NOT add duplicate listeners here.
|
||||
|
||||
@@ -2222,7 +2236,8 @@ function switchTab(tab) {
|
||||
if (tab === 'jobs') loadJobs();
|
||||
if (tab === 'missions') loadMissions();
|
||||
if (tab === 'routines') loadRoutines();
|
||||
if (tab === 'logs') applyLogFilters();
|
||||
if (tab === 'logs') { connectLogSSE(); applyLogFilters(); }
|
||||
else if (logEventSource) { logEventSource.close(); logEventSource = null; }
|
||||
if (tab === 'settings') {
|
||||
loadSettingsSubtab(currentSettingsSubtab);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user