feat(terminal): enhance WebSocket connection handling and port management
- Refactor WebSocket connection logic to dynamically fetch the port from the server, improving flexibility. - Introduce global variables to manage WebSocket server state and port, allowing for better control and error handling. - Update terminal drawer component to use the new port fetching mechanism, ensuring consistent connection behavior.
This commit is contained in:
parent
e49b74c990
commit
c084caf78c
9
apps/web/app/api/terminal/port/route.ts
Normal file
9
apps/web/app/api/terminal/port/route.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { getTerminalPort } from "@/lib/terminal-server";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export function GET() {
|
||||
const port = getTerminalPort();
|
||||
return NextResponse.json({ port });
|
||||
}
|
||||
@ -16,7 +16,7 @@ const MIN_DRAWER_HEIGHT = 180;
|
||||
const MAX_DRAWER_HEIGHT_RATIO = 0.75;
|
||||
const DEFAULT_DRAWER_HEIGHT = 280;
|
||||
const STORAGE_KEY = "dench-terminal-height";
|
||||
const WS_PORT = 3101;
|
||||
const DEFAULT_WS_PORT = 3101;
|
||||
const MAX_TERMINALS = 8;
|
||||
|
||||
function maxDrawerHeight(): number {
|
||||
@ -159,7 +159,7 @@ function TerminalViewport({
|
||||
termRef.current = terminal;
|
||||
fitRef.current = fitAddon;
|
||||
|
||||
const connectWs = () => {
|
||||
const connectWs = async () => {
|
||||
if (disposed) return;
|
||||
|
||||
// Fit now that the container has layout dimensions
|
||||
@ -167,8 +167,16 @@ function TerminalViewport({
|
||||
const cols = terminal.cols > 0 ? terminal.cols : 80;
|
||||
const rows = terminal.rows > 0 ? terminal.rows : 24;
|
||||
|
||||
let wsPort = DEFAULT_WS_PORT;
|
||||
try {
|
||||
const res = await fetch("/api/terminal/port");
|
||||
const json = await res.json();
|
||||
if (json.port) wsPort = json.port;
|
||||
} catch {}
|
||||
|
||||
if (disposed) return;
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||
const wsUrl = `${protocol}//127.0.0.1:${WS_PORT}`;
|
||||
const wsUrl = `${protocol}//127.0.0.1:${wsPort}`;
|
||||
const ws = new WebSocket(wsUrl);
|
||||
wsRef.current = ws;
|
||||
|
||||
|
||||
@ -11,12 +11,19 @@ interface TerminalSession {
|
||||
|
||||
const sessions = new Map<WebSocket, TerminalSession>();
|
||||
|
||||
let wss: WebSocketServer | null = null;
|
||||
let didFixSpawnHelper = false;
|
||||
const _g = globalThis as unknown as {
|
||||
__terminalWss?: WebSocketServer;
|
||||
__terminalDidFixSpawnHelper?: boolean;
|
||||
__terminalPort?: number;
|
||||
};
|
||||
|
||||
let wss: WebSocketServer | null = _g.__terminalWss ?? null;
|
||||
let didFixSpawnHelper = _g.__terminalDidFixSpawnHelper ?? false;
|
||||
|
||||
function ensureSpawnHelperExecutable() {
|
||||
if (didFixSpawnHelper || process.platform === "win32") return;
|
||||
didFixSpawnHelper = true;
|
||||
_g.__terminalDidFixSpawnHelper = true;
|
||||
try {
|
||||
const req = createRequire(import.meta.url);
|
||||
const pkgPath = req.resolve("node-pty/package.json");
|
||||
@ -163,16 +170,25 @@ export function startTerminalServer(port: number) {
|
||||
if (wss) return;
|
||||
|
||||
wss = new WebSocketServer({ port, host: "127.0.0.1" });
|
||||
_g.__terminalWss = wss;
|
||||
wss.on("connection", handleConnection);
|
||||
wss.on("listening", () => {
|
||||
_g.__terminalPort = port;
|
||||
});
|
||||
wss.on("error", (err) => {
|
||||
if ((err as NodeJS.ErrnoException).code === "EADDRINUSE") {
|
||||
console.warn(`[terminal] Port ${port} in use, retrying on ${port + 1}`);
|
||||
wss = null;
|
||||
_g.__terminalWss = undefined;
|
||||
startTerminalServer(port + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getTerminalPort(): number | null {
|
||||
return _g.__terminalPort ?? null;
|
||||
}
|
||||
|
||||
export function stopTerminalServer() {
|
||||
if (!wss) return;
|
||||
for (const session of sessions.values()) {
|
||||
@ -181,4 +197,5 @@ export function stopTerminalServer() {
|
||||
sessions.clear();
|
||||
wss.close();
|
||||
wss = null;
|
||||
_g.__terminalWss = undefined;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user