From 0f22e097bac1f2ff65c9098fbeffab4b5ed4fc45 Mon Sep 17 00:00:00 2001 From: foxhui Date: Thu, 11 Dec 2025 19:21:02 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=90=AF=E5=8A=A8VNC?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E6=97=B6=E7=AB=AF=E5=8F=A3=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E5=86=B2=E7=AA=81=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/server.js b/server.js index cde84b6..9432ec3 100644 --- a/server.js +++ b/server.js @@ -8,6 +8,7 @@ import { logger } from './lib/utils/logger.js'; import crypto from 'crypto'; import { spawn, spawnSync } from 'child_process'; import os from 'os'; +import net from 'net'; // ==================== 命令行参数处理 ==================== @@ -21,10 +22,48 @@ function checkCommand(cmd) { return result.status === 0; } +/** + * 检查端口是否可用 + * @param {number} port - 端口号 + * @returns {Promise} + */ +function isPortAvailable(port) { + return new Promise((resolve) => { + const server = net.createServer(); + + server.once('error', () => { + resolve(false); + }); + + server.once('listening', () => { + server.close(); + resolve(true); + }); + + server.listen(port); + }); +} + +/** + * 查找可用的 VNC 端口 + * @param {number} startPort - 起始端口 (默认 5900) + * @param {number} maxAttempts - 最大尝试次数 (默认 10) + * @returns {Promise} + */ +async function findAvailableVncPort(startPort = 5900, maxAttempts = 10) { + for (let i = 0; i < maxAttempts; i++) { + const port = startPort + i; + if (await isPortAvailable(port)) { + return port; + } + } + return null; +} + /** * 处理 Xvfb 和 VNC 启动参数(仅 Linux) */ -function handleDisplayParams() { +async function handleDisplayParams() { const args = process.argv.slice(2); const hasXvfb = args.includes('-xvfb'); const hasVnc = args.includes('-vnc'); @@ -72,10 +111,21 @@ function handleDisplayParams() { } const display = process.env.DISPLAY || ':99'; - logger.info('服务器', '正在启动 VNC 服务器...'); + + // 自动查找可用端口 (从 5900 开始) + logger.info('服务器', '正在查找可用的 VNC 端口...'); + const vncPort = await findAvailableVncPort(5900, 10); + + if (!vncPort) { + logger.error('服务器', '无法找到可用的 VNC 端口 (已尝试 5900-5909)'); + process.exit(1); + } + + logger.info('服务器', `正在启动 VNC 服务器 (端口 ${vncPort})...`); const vncProcess = spawn('x11vnc', [ '-display', display, + '-rfbport', vncPort.toString(), '-localhost', '-nopw', '-once', @@ -101,8 +151,8 @@ function handleDisplayParams() { process.exit(0); }); - logger.info('服务器', 'VNC 服务器已启动'); - logger.warn('服务器', '连接方式: 在本地运行 VNC 客户端连接 5900 端口'); + logger.info('服务器', 'VNC 服务器已成功启动'); + logger.warn('服务器', `VNC 连接端口: ${vncPort}`); } return; @@ -153,7 +203,7 @@ function handleDisplayParams() { } // 执行参数处理 -const displayResult = handleDisplayParams(); +const displayResult = await handleDisplayParams(); if (displayResult === 'XVFB_REDIRECT') { // 已经重定向到 Xvfb,不再继续执行 // 这个进程将等待子进程退出