From 894fd17d1a3d89aa149500f6a49eb00a95c3c4ed Mon Sep 17 00:00:00 2001 From: imbytecat Date: Sun, 8 Feb 2026 18:38:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(desktop):=20=E5=8A=A8=E6=80=81=E5=88=86?= =?UTF-8?q?=E9=85=8D=20sidecar=20=E7=AB=AF=E5=8F=A3=E6=9B=BF=E4=BB=A3?= =?UTF-8?q?=E7=A1=AC=E7=BC=96=E7=A0=81=EF=BC=8C=E9=81=BF=E5=85=8D=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用 net.createServer().listen(0) 探测可用端口,通过 PORT 环境变量 传递给 sidecar binary(VS Code language server 同款模式) --- apps/desktop/src/main/index.ts | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index c91ef7c..eeaf345 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -1,13 +1,24 @@ import { spawn } from 'node:child_process' +import type { AddressInfo } from 'node:net' +import { createServer } from 'node:net' import { join } from 'node:path' import { app, BrowserWindow, shell } from 'electron' const DEV_SERVER_URL = 'http://localhost:3000' -const PROD_SERVER_PORT = 23_410 let mainWindow: BrowserWindow | null = null let serverProcess: ReturnType | null = null +const getAvailablePort = (): Promise => + new Promise((resolve, reject) => { + const server = createServer() + server.listen(0, () => { + const { port } = server.address() as AddressInfo + server.close(() => resolve(port)) + }) + server.on('error', reject) + }) + const isServerReady = async (url: string): Promise => { try { const response = await fetch(url, { method: 'HEAD' }) @@ -29,14 +40,14 @@ const waitForServer = async ( return false } -const spawnServer = (): string => { +const spawnServer = (port: number): string => { const binaryName = process.platform === 'win32' ? 'server.exe' : 'server' const binaryPath = join(process.resourcesPath, binaryName) serverProcess = spawn(binaryPath, [], { env: { ...process.env, - PORT: String(PROD_SERVER_PORT), + PORT: String(port), HOST: '127.0.0.1', }, stdio: 'pipe', @@ -54,14 +65,15 @@ const spawnServer = (): string => { console.error('Failed to start server:', err) }) - return `http://127.0.0.1:${PROD_SERVER_PORT}` + return `http://127.0.0.1:${port}` } -const getServerUrl = (): string => { +const getServerUrl = async (): Promise => { if (!app.isPackaged) { return DEV_SERVER_URL } - return spawnServer() + const port = await getAvailablePort() + return spawnServer(port) } const createWindow = async () => { @@ -87,7 +99,7 @@ const createWindow = async () => { } mainWindow.show() - const serverUrl = getServerUrl() + const serverUrl = await getServerUrl() console.log(`Waiting for server at ${serverUrl}...`) const ready = await waitForServer(serverUrl)