fix: add pong/timeout detection to prevent silent connection hangs
Deploy Dashboard / deploy (push) Successful in 49s

Merge pull request #35: Fix pong/timeout detection
This commit was merged in pull request #35.
This commit is contained in:
2026-03-11 23:58:36 +08:00
2 changed files with 26 additions and 1 deletions
+1
View File
@@ -180,6 +180,7 @@ async def ws_endpoint(websocket: WebSocket, host: str = Query("nas"), token: str
process.stdin.write(data)
elif "text" in msg and msg["text"]:
if msg["text"] == "__ping__":
await websocket.send_text("__pong__")
continue
process.stdin.write(msg["text"].encode())
except Exception as e:
+25 -1
View File
@@ -190,18 +190,24 @@
const proto = location.protocol === "https:" ? "wss:" : "ws:";
let heartbeat = null;
let pongTimeout = null;
let reconnectTimer = null;
let closedManually = false;
let reconnecting = false;
let authRecoveryInFlight = false;
let reconnectAttempts = 0;
const MAX_RECONNECT_DELAY = 30000;
const PONG_TIMEOUT = 5000; // 5s to receive pong
function clearHeartbeat() {
if (heartbeat) {
clearInterval(heartbeat);
heartbeat = null;
}
if (pongTimeout) {
clearTimeout(pongTimeout);
pongTimeout = null;
}
}
function handleAuthExpired(reason = "Session expired — please log in again") {
@@ -280,7 +286,15 @@
sendSize(ws);
clearHeartbeat();
heartbeat = setInterval(() => {
if (ws.readyState === 1) ws.send("__ping__");
if (ws.readyState === 1) {
ws.send("__ping__");
// Set timeout to detect missing pong
pongTimeout = setTimeout(() => {
if (ws.readyState === 1) {
ws.close(1000, "keepalive ping timeout");
}
}, PONG_TIMEOUT);
}
}, 12000);
const d = tabData.get(tabId);
if (d) {
@@ -293,6 +307,16 @@
}
};
ws.onmessage = (e) => {
// Check for text pong response
if (typeof e.data === 'string' && e.data === '__pong__') {
// Clear the pong timeout - connection is alive
if (pongTimeout) {
clearTimeout(pongTimeout);
pongTimeout = null;
}
return;
}
const data = new Uint8Array(e.data);
const isPersistenceMessage = tab.persistent
&& data.length >= PERSISTENCE_STATUS_PREFIX_BYTES.length