diff --git a/lib/frpc.js b/lib/frpc.js index d0cd75b..643a97e 100644 --- a/lib/frpc.js +++ b/lib/frpc.js @@ -16,47 +16,43 @@ const FRPC_CONFIG = path.join(CONFIG_DIR, 'frpc.toml'); const FRP_VERSION = '0.62.0'; /** - * 启动 openclaw dashboard(若未运行),等待输出中出现 Dashboard URL, + * 启动 openclaw dashboard(后台运行),轮询日志文件等待 Dashboard URL 出现, * 解析并返回 { dashboard_token, dashboard_port }。 - * 超时或命令不存在时返回 {}。 - * dashboard 进程会持续运行(不会被 kill)。 + * 超时(10s)或命令不存在时返回 {}。 */ function getDashboardInfo() { return new Promise((resolve) => { - let done = false; - const finish = (result) => { - if (!done) { done = true; resolve(result); } - }; + const tmpLog = '/tmp/clawd-dashboard.log'; - // 8 秒内未收到 URL 则放弃 - const timer = setTimeout(() => finish({}), 8000); - - let proc; + // 后台启动 dashboard,输出重定向到日志文件 try { - proc = spawn('openclaw', ['dashboard'], { - stdio: ['ignore', 'pipe', 'pipe'], - }); + execSync(`openclaw dashboard > ${tmpLog} 2>&1 &`, { shell: true, timeout: 3000 }); } catch (e) { - clearTimeout(timer); - return finish({}); + // 已在运行或命令不存在,继续轮询 } - const handleLine = (line) => { - const match = line.match(/Dashboard URL:.*:(\d+)\/#token=([a-f0-9]+)/); - if (match) { - clearTimeout(timer); - const port = parseInt(match[1], 10); - const token = match[2]; - console.log(`[frpc] openclaw dashboard: port=${port}, token=${token.substring(0, 8)}...`); - // 进程继续运行(dashboard 服务),不 kill - finish({ dashboard_port: port, dashboard_token: token }); - } - }; + // 每秒读一次日志文件,最多等 10 秒 + let attempts = 0; + const interval = setInterval(() => { + attempts++; + try { + const content = fs.readFileSync(tmpLog, 'utf8'); + const match = content.match(/Dashboard URL:.*:(\d+)\/#token=([a-f0-9]+)/); + if (match) { + clearInterval(interval); + const port = parseInt(match[1], 10); + const token = match[2]; + console.log(`[frpc] openclaw dashboard: port=${port}, token=${token.substring(0, 8)}...`); + resolve({ dashboard_port: port, dashboard_token: token }); + return; + } + } catch (e) { /* 文件暂时不存在 */ } - proc.stdout.on('data', d => handleLine(d.toString())); - proc.stderr.on('data', d => handleLine(d.toString())); - proc.on('error', () => { clearTimeout(timer); finish({}); }); - proc.on('exit', () => { clearTimeout(timer); finish({}); }); + if (attempts >= 10) { + clearInterval(interval); + resolve({}); + } + }, 1000); }); }