mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-05-04 00:21:19 +00:00
fix: auto-close tab on graceful SSH disconnect (exit/Ctrl+D) (#723)
Distinguish between graceful shell exit and unexpected disconnection using the stream close event's exit code. When the shell exits normally (code != null), send "session_ended" instead of "disconnected". The frontend auto-closes the tab on session_ended, and shows the reconnect overlay only on unexpected disconnections. Closes Termix-SSH/Support#643
This commit is contained in:
@@ -1503,15 +1503,24 @@ wss.on("connection", async (ws: WebSocket, req) => {
|
||||
}
|
||||
});
|
||||
|
||||
stream.on("close", () => {
|
||||
stream.on("close", (code: number | null) => {
|
||||
const session = sessionManager.getSession(boundSessionId);
|
||||
if (session?.attachedWs?.readyState === WebSocket.OPEN) {
|
||||
session.attachedWs.send(
|
||||
JSON.stringify({
|
||||
type: "disconnected",
|
||||
message: "Connection lost",
|
||||
}),
|
||||
);
|
||||
if (code != null) {
|
||||
session.attachedWs.send(
|
||||
JSON.stringify({
|
||||
type: "session_ended",
|
||||
code,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
session.attachedWs.send(
|
||||
JSON.stringify({
|
||||
type: "disconnected",
|
||||
message: "Connection lost",
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
if (boundSessionId) {
|
||||
sessionManager.destroySession(boundSessionId);
|
||||
|
||||
@@ -1676,6 +1676,7 @@
|
||||
"automaticFallback": "Automatically trying {{method}} authentication...",
|
||||
"totpTimeout": "TOTP verification timeout. Please reconnect.",
|
||||
"passwordTimeout": "Password verification timeout. Please reconnect.",
|
||||
"sessionEnded": "Session ended.",
|
||||
"connectionRejected": "Connection rejected by server. Please check your authentication and network configuration.",
|
||||
"hostKeyRejected": "SSH host key verification rejected. Connection cancelled.",
|
||||
"sessionTakenOver": "Session was opened in another tab. Reconnecting...",
|
||||
|
||||
@@ -1187,6 +1187,14 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
|
||||
);
|
||||
}
|
||||
}, 100);
|
||||
} else if (msg.type === "session_ended") {
|
||||
wasDisconnectedBySSH.current = true;
|
||||
setIsConnected(false);
|
||||
setIsConnecting(false);
|
||||
shouldNotReconnectRef.current = true;
|
||||
if (onClose) {
|
||||
onClose();
|
||||
}
|
||||
} else if (msg.type === "disconnected") {
|
||||
wasDisconnectedBySSH.current = true;
|
||||
shouldNotReconnectRef.current = true;
|
||||
|
||||
@@ -729,6 +729,13 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
|
||||
);
|
||||
}
|
||||
}, 100);
|
||||
} else if (msg.type === "session_ended") {
|
||||
wasDisconnectedBySSH.current = true;
|
||||
shouldNotReconnectRef.current = true;
|
||||
isConnectingRef.current = false;
|
||||
setIsConnected(false);
|
||||
setIsConnecting(false);
|
||||
updateConnectionError(t("terminal.sessionEnded"));
|
||||
} else if (msg.type === "disconnected") {
|
||||
wasDisconnectedBySSH.current = true;
|
||||
isConnectingRef.current = false;
|
||||
|
||||
Reference in New Issue
Block a user