fix: keep terminal sessions alive #25
@@ -72,6 +72,8 @@ async def ws_endpoint(websocket: WebSocket, host: str = Query("nas")):
|
|||||||
conn = await asyncssh.connect(
|
conn = await asyncssh.connect(
|
||||||
h["host"], username=h["user"],
|
h["host"], username=h["user"],
|
||||||
client_keys=[h["key"]], known_hosts=_known_hosts,
|
client_keys=[h["key"]], known_hosts=_known_hosts,
|
||||||
|
keepalive_interval=30,
|
||||||
|
keepalive_count_max=3,
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
_active_sessions.discard(session_id)
|
_active_sessions.discard(session_id)
|
||||||
@@ -108,6 +110,8 @@ async def ws_endpoint(websocket: WebSocket, host: str = Query("nas")):
|
|||||||
else:
|
else:
|
||||||
process.stdin.write(data)
|
process.stdin.write(data)
|
||||||
elif "text" in msg and msg["text"]:
|
elif "text" in msg and msg["text"]:
|
||||||
|
if msg["text"] == "__ping__":
|
||||||
|
continue
|
||||||
process.stdin.write(msg["text"].encode())
|
process.stdin.write(msg["text"].encode())
|
||||||
except WebSocketDisconnect:
|
except WebSocketDisconnect:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -122,6 +122,7 @@
|
|||||||
if (d) {
|
if (d) {
|
||||||
d.voice?.destroy();
|
d.voice?.destroy();
|
||||||
d.ro?.disconnect();
|
d.ro?.disconnect();
|
||||||
|
if (d.heartbeat) clearInterval(d.heartbeat);
|
||||||
d.term?.element?.removeEventListener("dragover", d.handleDragOver);
|
d.term?.element?.removeEventListener("dragover", d.handleDragOver);
|
||||||
d.term?.element?.removeEventListener("drop", d.handleDrop);
|
d.term?.element?.removeEventListener("drop", d.handleDrop);
|
||||||
d.term?.textarea?.removeEventListener("paste", d.handlePaste);
|
d.term?.textarea?.removeEventListener("paste", d.handlePaste);
|
||||||
@@ -180,6 +181,10 @@
|
|||||||
ws.onerror = () => updateTab(tabId, { connected: false, error: "Connection failed" });
|
ws.onerror = () => updateTab(tabId, { connected: false, error: "Connection failed" });
|
||||||
term.onData((data) => ws.readyState === 1 && ws.send(new TextEncoder().encode(data)));
|
term.onData((data) => ws.readyState === 1 && ws.send(new TextEncoder().encode(data)));
|
||||||
|
|
||||||
|
const heartbeat = setInterval(() => {
|
||||||
|
if (ws.readyState === 1) ws.send("__ping__");
|
||||||
|
}, 25000);
|
||||||
|
|
||||||
const handleDragOver = (e) => {
|
const handleDragOver = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
@@ -211,7 +216,7 @@
|
|||||||
ro.observe(el);
|
ro.observe(el);
|
||||||
const voice = new VoiceSession(() => { voiceTick++; });
|
const voice = new VoiceSession(() => { voiceTick++; });
|
||||||
voice.attach(term, ws);
|
voice.attach(term, ws);
|
||||||
tabData.set(tabId, { ws, term, ro, el, voice, handleDragOver, handleDrop, handlePaste });
|
tabData.set(tabId, { ws, term, ro, el, voice, heartbeat, handleDragOver, handleDrop, handlePaste });
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +227,7 @@
|
|||||||
tabData.forEach((d) => {
|
tabData.forEach((d) => {
|
||||||
d.voice?.destroy();
|
d.voice?.destroy();
|
||||||
d.ro?.disconnect();
|
d.ro?.disconnect();
|
||||||
|
if (d.heartbeat) clearInterval(d.heartbeat);
|
||||||
d.term?.element?.removeEventListener("dragover", d.handleDragOver);
|
d.term?.element?.removeEventListener("dragover", d.handleDragOver);
|
||||||
d.term?.element?.removeEventListener("drop", d.handleDrop);
|
d.term?.element?.removeEventListener("drop", d.handleDrop);
|
||||||
d.term?.textarea?.removeEventListener("paste", d.handlePaste);
|
d.term?.textarea?.removeEventListener("paste", d.handlePaste);
|
||||||
|
|||||||
Reference in New Issue
Block a user