mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-07-28 04:49:09 +00:00
feat(extension): lazy-connect — only maintain WebSocket when actively in room
- Add connectIntent flag to gate all reconnect attempts - Only auto-connect on startup if roomId exists in storage - Close socket + stop reconnect after leaveRoom or idleLeave - Preserve existing behavior 1:1 when actively in a room - Guard force-sync state and peer list clearing during transient disconnects - Guard WEB_JOIN_REQUEST against empty sanitized roomId
This commit is contained in:
+46
-19
@@ -176,6 +176,7 @@ let reconnectAttempts = 0;
|
||||
let currentServerUrl = null;
|
||||
let roomIdleSince = null;
|
||||
let lastContentHeartbeatAt = null;
|
||||
let connectIntent = false;
|
||||
const MAX_RECONNECT_ATTEMPTS = 20;
|
||||
const _RECONNECT_BASE_DELAY = 500;
|
||||
const _RECONNECT_MAX_DELAY = 5000;
|
||||
@@ -404,7 +405,9 @@ function clearTargetTabForIdle() {
|
||||
|
||||
async function leaveRoomAfterIdleGrace(reason) {
|
||||
if (!currentRoom) return;
|
||||
connectIntent = false;
|
||||
emit(EVENTS.LEAVE_ROOM, { peerId });
|
||||
forceDisconnect();
|
||||
currentRoom = null;
|
||||
currentTabId = null;
|
||||
currentTabTitle = null;
|
||||
@@ -457,7 +460,9 @@ async function connect() {
|
||||
addLog('Browser is offline. Waiting...', 'warn');
|
||||
broadcastConnectionStatus('offline');
|
||||
isConnecting = false;
|
||||
scheduleReconnect();
|
||||
if (currentRoom || connectIntent) {
|
||||
scheduleReconnect();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -564,25 +569,32 @@ async function connect() {
|
||||
isNamespaceJoined = false;
|
||||
stopPing();
|
||||
|
||||
isForceSyncInitiator = false;
|
||||
forceSyncAcks.clear();
|
||||
if (forceSyncTimeout) clearTimeout(forceSyncTimeout);
|
||||
chrome.storage.session.set({
|
||||
isForceSyncInitiator: false,
|
||||
forceSyncAcks: [],
|
||||
forceSyncDeadline: null
|
||||
}).catch(() => {});
|
||||
if (!connectIntent && !currentRoom) {
|
||||
isForceSyncInitiator = false;
|
||||
forceSyncAcks.clear();
|
||||
if (forceSyncTimeout) clearTimeout(forceSyncTimeout);
|
||||
chrome.storage.session.set({
|
||||
isForceSyncInitiator: false,
|
||||
forceSyncAcks: [],
|
||||
forceSyncDeadline: null
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
|
||||
if (currentRoom) {
|
||||
if (currentRoom && !connectIntent) {
|
||||
currentRoom.peers = [];
|
||||
if (storageInitialized) chrome.storage.session.set({ currentRoom }).catch(() => {});
|
||||
chrome.runtime.sendMessage({ type: 'PEER_UPDATE', peers: [] }).catch(() => {});
|
||||
}
|
||||
broadcastConnectionStatus('disconnected');
|
||||
addLog('Disconnected. Scheduling reconnect...', 'warn');
|
||||
socket = null;
|
||||
scheduleReconnect();
|
||||
if (currentRoom || connectIntent) {
|
||||
addLog('Disconnected. Scheduling reconnect...', 'warn');
|
||||
socket = null;
|
||||
scheduleReconnect();
|
||||
} else {
|
||||
addLog('Disconnected. No active session — staying disconnected.', 'info');
|
||||
socket = null;
|
||||
}
|
||||
};
|
||||
|
||||
socket.onerror = () => {
|
||||
@@ -597,7 +609,9 @@ async function connect() {
|
||||
const errMsg = (e && e.message) ? e.message : String(e || 'Unknown connection error');
|
||||
addLog(errMsg, logType);
|
||||
broadcastConnectionStatus('disconnected');
|
||||
scheduleReconnect();
|
||||
if (currentRoom || connectIntent) {
|
||||
scheduleReconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -738,6 +752,9 @@ function sendPing() {
|
||||
addLog('Ping timeout reached, force disconnecting to trigger reconnect', 'warn');
|
||||
pendingPingT = null;
|
||||
forceDisconnect();
|
||||
if (currentRoom || connectIntent) {
|
||||
scheduleReconnect();
|
||||
}
|
||||
}
|
||||
pingTimeout = null;
|
||||
}, 5000);
|
||||
@@ -1334,7 +1351,7 @@ chrome.alarms.onAlarm.addListener(async (alarm) => {
|
||||
if (alarm.name === 'keepAlive') {
|
||||
chrome.storage.session.get('keepAlive', () => {});
|
||||
if (!socket || socket.readyState !== WebSocket.OPEN) {
|
||||
if (!reconnectFailed) {
|
||||
if (!reconnectFailed && (currentRoom || connectIntent)) {
|
||||
connect();
|
||||
}
|
||||
} else if (currentRoom) {
|
||||
@@ -1417,6 +1434,7 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
||||
|
||||
if (message.type === 'CONNECT') {
|
||||
const settings = await getSettings();
|
||||
connectIntent = !!settings.roomId;
|
||||
const desiredUrl = resolveServerUrl(settings);
|
||||
|
||||
if (settings.roomId && currentRoom && currentRoom.roomId === settings.roomId && socket && socket.readyState === WebSocket.OPEN && isNamespaceJoined && desiredUrl === currentServerUrl) {
|
||||
@@ -1439,7 +1457,7 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
||||
}
|
||||
if (desiredUrl !== currentServerUrl || !socket || socket.readyState !== WebSocket.OPEN || !isNamespaceJoined) {
|
||||
if (desiredUrl !== currentServerUrl) forceDisconnect();
|
||||
connect();
|
||||
if (settings.roomId) connect();
|
||||
} else if (settings.roomId) {
|
||||
emit(EVENTS.JOIN_ROOM, {
|
||||
roomId: settings.roomId,
|
||||
@@ -1452,6 +1470,7 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
||||
}
|
||||
sendResponse({ status: 'ok' });
|
||||
} else if (message.type === 'RETRY_CONNECT') {
|
||||
connectIntent = true;
|
||||
reconnectFailed = false;
|
||||
reconnectStartTime = null;
|
||||
reconnectAttempts = 0;
|
||||
@@ -1480,6 +1499,7 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
||||
ping: currentPingMs
|
||||
});
|
||||
} else if (message.type === 'LEAVE_ROOM') {
|
||||
connectIntent = false;
|
||||
resetAudioProcessingInTab(currentTabId);
|
||||
emit(EVENTS.LEAVE_ROOM, { peerId });
|
||||
currentRoom = null;
|
||||
@@ -1510,8 +1530,10 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
||||
episodeLobby: null,
|
||||
expectedAcksCount: 0
|
||||
});
|
||||
chrome.storage.local.set({ roomId: '', password: '' }).catch(() => {});
|
||||
addLog('Left Room', 'info');
|
||||
chrome.runtime.sendMessage({ type: 'PEER_UPDATE', peers: [] }).catch(() => {});
|
||||
forceDisconnect();
|
||||
sendResponse({ status: 'ok' });
|
||||
} else if (message.type === 'CLEAR_LOGS') {
|
||||
logs = [];
|
||||
@@ -1526,6 +1548,8 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
||||
} else if (message.type === 'WEB_JOIN_REQUEST') {
|
||||
const { roomId: rawRoomId, password, useCustomServer, serverUrl } = message;
|
||||
const roomId = typeof rawRoomId === 'string' ? rawRoomId.replace(/[^a-zA-Z0-9\-]/g, '') : '';
|
||||
connectIntent = !!roomId;
|
||||
if (!roomId) { sendResponse({ error: 'invalid_room_id' }); return; }
|
||||
chrome.storage.local.set({
|
||||
roomId,
|
||||
password,
|
||||
@@ -1554,7 +1578,7 @@ async function handleAsyncMessage(message, sender, sendResponse) {
|
||||
if (desiredUrl !== currentServerUrl || !socket || socket.readyState !== WebSocket.OPEN || !isNamespaceJoined) {
|
||||
if (desiredUrl !== currentServerUrl) forceDisconnect();
|
||||
connect();
|
||||
} else {
|
||||
} else if (roomId) {
|
||||
emit(EVENTS.JOIN_ROOM, {
|
||||
roomId,
|
||||
password,
|
||||
@@ -1939,5 +1963,8 @@ chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, _tab) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Initial Connect
|
||||
connect();
|
||||
// Initial Connect — only if user has an active room configuration
|
||||
getSettings().then(settings => {
|
||||
connectIntent = !!settings.roomId;
|
||||
if (connectIntent) connect();
|
||||
}).catch(() => connectIntent = false);
|
||||
|
||||
Reference in New Issue
Block a user