fix: add pong/timeout detection to prevent silent connection hangs
Deploy Dashboard / deploy (push) Successful in 49s
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:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user