Lines 191-231javascript
191// 合并模式:优先连接已运行的 web 端引擎(127.0.0.1:3080)——同一引擎、同一数据;
192// 没有则自己启动(固定 3080 端口,天然防止双实例写同一数据根)。
193const WEB_PORT = 3080;
194function probePort(port, timeoutMs, cb) {
195 httpGet(`http://127.0.0.1:${port}/`, timeoutMs)
196 .then(() => { log('info', `probe ${port}: alive`); cb(true); })
197 .catch((e) => { log('warn', `probe ${port}: not responding (${e && e.message ? e.message : e})`); cb(false
199function httpGet(url, timeoutMs) {
200 return new Promise((resolve, reject) => {
201 const req = require('node:http').get(url, (res) => { res.resume(); resolve(res.statusCode); });
202 req.setTimeout(timeoutMs || 1500, () => { req.destroy(new Error('timeout')); });
203 req.on('error', reject);
206function startHarness() {
208 // 1. 检测 web 端引擎是否已在跑
209 probePort(WEB_PORT, 1500, (alive) => {
211 log('info', `web engine already running at 127.0.0.1:${WEB_PORT} — connecting as another entry`);
212 onHarnessReady(`http://127.0.0.1:${WEB_PORT}`);
218function spawnEngine() {
219 const { command, args } = resolveLauncher();
220 const fullArgs = [...args, '--host', '127.0.0.1', '--port', String(WEB_PORT)];
221 log('info', `spawning harness: ${command} ${fullArgs.join(' ')} (DSH_HOME=${dataHome})`);
223 const spawnEnv = { ...process.env, DSH_HOME: dataHome };
224 if (process.platform === 'win32' && command === 'npx') {
225 // npx 是 .cmd,须经 cmd /c 执行;windowsHide 隐藏命令窗口
226 const line = ['npx', ...fullArgs].map((a) => (/\s/.test(a) ? `"${a}"` : a)).join(' ');
227 proc = spawn(process.env.ComSpec || 'cmd.exe', ['/d', '/s', '/c', line], { windowsHide: true, env: spawnEnv, stdio: ['ignore', 'pipe', 'pipe'] });
228 } else {
HighSame File Env Network Execution
A single source file combines environment access, network access, and code or shell execution; review context before blocking.
launcher/main.jsView on unpkg · L211 229 proc = spawn(command, fullArgs, { windowsHide: true, env: spawnEnv, stdio: ['ignore', 'pipe', 'pipe'] });