panrouter 6.3.4 → 6.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/pool-worker.mjs +87 -10
package/package.json
CHANGED
package/pool-worker.mjs
CHANGED
|
@@ -145,6 +145,10 @@ function connectToHub() {
|
|
|
145
145
|
ws.send(JSON.stringify({ type: "pong" }));
|
|
146
146
|
break;
|
|
147
147
|
|
|
148
|
+
case "test":
|
|
149
|
+
handleTestRequest(msg);
|
|
150
|
+
break;
|
|
151
|
+
|
|
148
152
|
case "upgrade":
|
|
149
153
|
handleUpgrade();
|
|
150
154
|
break;
|
|
@@ -266,6 +270,17 @@ async function doRestart() {
|
|
|
266
270
|
// ─── 处理来自主控的请求 ─────────────────────────────────────────────────────
|
|
267
271
|
|
|
268
272
|
function handleIncomingRequest(msg) {
|
|
273
|
+
// ponytail: 不阻塞请求,但如果 watchdog 标记了挂了就先重启
|
|
274
|
+
if (!_serverReady) {
|
|
275
|
+
isPortOpen(SERVER_PORT).then(open => {
|
|
276
|
+
if (!open) {
|
|
277
|
+
log(`9router 不在线,尝试重启`, "WARN");
|
|
278
|
+
killPort(SERVER_PORT);
|
|
279
|
+
trySpawn9router();
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
269
284
|
const body = msg.body || "";
|
|
270
285
|
|
|
271
286
|
const options = {
|
|
@@ -337,6 +352,29 @@ function safeSend(data) {
|
|
|
337
352
|
}
|
|
338
353
|
}
|
|
339
354
|
|
|
355
|
+
// ─── 节点连通性测试 ─────────────────────────────────────────────────────────
|
|
356
|
+
|
|
357
|
+
function handleTestRequest(msg) {
|
|
358
|
+
const testReq = http.request({
|
|
359
|
+
hostname: "127.0.0.1",
|
|
360
|
+
port: SERVER_PORT,
|
|
361
|
+
path: "/dashboard",
|
|
362
|
+
method: "GET",
|
|
363
|
+
timeout: 8000,
|
|
364
|
+
}, (res) => {
|
|
365
|
+
// 只要收到响应就算通
|
|
366
|
+
let body = "";
|
|
367
|
+
res.on("data", (c) => body += c);
|
|
368
|
+
res.on("end", () => {
|
|
369
|
+
safeSend({ type: "test_result", reqId: msg.reqId, ok: true, status: res.statusCode, detail: body.slice(0, 200) });
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
testReq.on("error", (err) => {
|
|
373
|
+
safeSend({ type: "test_result", reqId: msg.reqId, ok: false, error: err.message });
|
|
374
|
+
});
|
|
375
|
+
testReq.end();
|
|
376
|
+
}
|
|
377
|
+
|
|
340
378
|
// ─── 心跳保活(每 25 秒发送 ping,避免 Cloudflare 闲置超时) ─────────────────
|
|
341
379
|
|
|
342
380
|
function startHeartbeat() {
|
|
@@ -413,7 +451,7 @@ function ensureServer() {
|
|
|
413
451
|
function _ensureServer() {
|
|
414
452
|
const setupScript = path.join(__dirname, "setup-9router.cjs");
|
|
415
453
|
if (!fs.existsSync(setupScript)) {
|
|
416
|
-
log("找不到 setup-9router.cjs
|
|
454
|
+
log("找不到 setup-9router.cjs,直接启动 9router", "WARN");
|
|
417
455
|
trySpawn9router();
|
|
418
456
|
poll9router();
|
|
419
457
|
return;
|
|
@@ -423,19 +461,23 @@ function _ensureServer() {
|
|
|
423
461
|
const child = spawn(process.execPath, [setupScript], {
|
|
424
462
|
cwd: __dirname, stdio: "inherit",
|
|
425
463
|
});
|
|
464
|
+
// 等安装完再启动 9router — 统一用 --tray 模式,setup 自己开的 cmd 窗口让它去
|
|
426
465
|
child.on("exit", () => {
|
|
427
|
-
log("
|
|
466
|
+
log("安装完成,正在启动 9router...");
|
|
428
467
|
trySpawn9router();
|
|
429
468
|
});
|
|
430
|
-
|
|
431
469
|
poll9router();
|
|
432
470
|
}
|
|
433
471
|
|
|
434
472
|
function trySpawn9router() {
|
|
435
473
|
try {
|
|
436
|
-
|
|
437
|
-
|
|
474
|
+
// ponytail: --tray 跳过 TTY 菜单(否则无 TTY 环境 3 秒自杀)
|
|
475
|
+
// --skip-update 跳过 npm registry 检查(手机网络不稳定)
|
|
476
|
+
// 不用 npx,9router 已被 setup-9router.cjs 全局安装
|
|
477
|
+
const r = spawn("9router", ["--tray", "--skip-update"], {
|
|
478
|
+
detached: true, stdio: ["ignore", "ignore", "pipe"], shell: true,
|
|
438
479
|
});
|
|
480
|
+
r.stderr?.on("data", (d) => log(`9router 错误: ${d.toString().trim()}`, "ERR"));
|
|
439
481
|
r.unref();
|
|
440
482
|
} catch (e) {
|
|
441
483
|
log(`启动 9router 失败: ${e.message}`, "ERR");
|
|
@@ -443,14 +485,47 @@ function trySpawn9router() {
|
|
|
443
485
|
}
|
|
444
486
|
|
|
445
487
|
async function poll9router() {
|
|
446
|
-
|
|
488
|
+
const deadline = Date.now() + 30000;
|
|
489
|
+
while (Date.now() < deadline) {
|
|
447
490
|
if (await isPortOpen(SERVER_PORT)) {
|
|
448
491
|
_serverReady = true;
|
|
449
492
|
log(`9router 已就绪 (端口 ${SERVER_PORT})`, "OK");
|
|
450
|
-
return;
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
496
|
+
}
|
|
497
|
+
log(`等待 9router 超时,继续后台重试`, "WARN");
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// ponytail: 每隔 30 秒检查 9router 是否活着,死了就重启
|
|
502
|
+
let watchdogTimer = null;
|
|
503
|
+
|
|
504
|
+
function startWatchdog() {
|
|
505
|
+
if (watchdogTimer) return;
|
|
506
|
+
watchdogTimer = setInterval(async () => {
|
|
507
|
+
if (await isPortOpen(SERVER_PORT)) return;
|
|
508
|
+
log(`9router 无响应,正在重启...`, "WARN");
|
|
509
|
+
_serverReady = false;
|
|
510
|
+
killPort(SERVER_PORT);
|
|
511
|
+
trySpawn9router();
|
|
512
|
+
// 等待最多 15 秒
|
|
513
|
+
for (let i = 0; i < 15; i++) {
|
|
514
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
515
|
+
if (await isPortOpen(SERVER_PORT)) {
|
|
516
|
+
_serverReady = true;
|
|
517
|
+
log(`9router 已恢复`, "OK");
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
451
520
|
}
|
|
452
|
-
|
|
453
|
-
|
|
521
|
+
log(`9router 重启失败,下次再试`, "ERR");
|
|
522
|
+
}, 30000);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function stopWatchdog() {
|
|
526
|
+
if (watchdogTimer) {
|
|
527
|
+
clearInterval(watchdogTimer);
|
|
528
|
+
watchdogTimer = null;
|
|
454
529
|
}
|
|
455
530
|
}
|
|
456
531
|
|
|
@@ -488,6 +563,7 @@ function gracefulShutdown() {
|
|
|
488
563
|
|
|
489
564
|
log("收到关机指令,正在安全退出...", "OFF");
|
|
490
565
|
|
|
566
|
+
stopWatchdog();
|
|
491
567
|
stopHeartbeat();
|
|
492
568
|
if (reconnectTimer) {
|
|
493
569
|
clearTimeout(reconnectTimer);
|
|
@@ -528,11 +604,12 @@ export async function start() {
|
|
|
528
604
|
|
|
529
605
|
log("节点看门狗已启动,等待公网入口...", "ON");
|
|
530
606
|
|
|
531
|
-
// 等 9router
|
|
607
|
+
// 等 9router 起来后打开守护
|
|
532
608
|
const checkReady = setInterval(async () => {
|
|
533
609
|
if (_serverReady || (await isPortOpen(SERVER_PORT))) {
|
|
534
610
|
_serverReady = true;
|
|
535
611
|
clearInterval(checkReady);
|
|
612
|
+
startWatchdog();
|
|
536
613
|
log("9router 已就绪,节点可正常处理请求", "ON");
|
|
537
614
|
}
|
|
538
615
|
}, 3000);
|