fix: add AP net monitor to detect cable unplug within 5s, reduce ping interval to 10s

Made-with: Cursor
This commit is contained in:
stswangzhiping
2026-03-20 08:14:31 +08:00
parent 5ba8b7bffa
commit e94e2bb10c

View File

@@ -12,8 +12,9 @@ const { hasInternet } = require('./network');
const led = require('./led'); const led = require('./led');
const MAX_BACKOFF_MS = 60_000; const MAX_BACKOFF_MS = 60_000;
const PONG_TIMEOUT_MS = 15_000; const PONG_TIMEOUT_MS = 8_000;
const PING_INTERVAL_MS = 30_000; const PING_INTERVAL_MS = 10_000;
const NET_MONITOR_MS = 5_000; // AP 模式网络监视间隔
const HEARTBEAT_INTERVAL_MS = 10_000; // 心跳间隔10 秒,用于快速感知网络状态 const HEARTBEAT_INTERVAL_MS = 10_000; // 心跳间隔10 秒,用于快速感知网络状态
const METRICS_EVERY_N = 3; // 每 N 次心跳采集一次指标(= 30 秒) const METRICS_EVERY_N = 3; // 每 N 次心跳采集一次指标(= 30 秒)
@@ -39,6 +40,9 @@ class ClawClient {
this._pingTimer = null; this._pingTimer = null;
this._awaitingPong = false; this._awaitingPong = false;
// AP 模式网络监视WS 连通后每 5s 检查,断网立即 terminate
this._netMonitorTimer = null;
// WS 连续失败计数open 时清零) // WS 连续失败计数open 时清零)
this._wsFailCount = 0; this._wsFailCount = 0;
// 是否曾经成功连接过(首次成功前不显示 Err0/AP // 是否曾经成功连接过(首次成功前不显示 Err0/AP
@@ -112,6 +116,7 @@ class ClawClient {
this._stopped = true; this._stopped = true;
this._clearHeartbeat(); this._clearHeartbeat();
this._clearPing(); this._clearPing();
this._clearNetMonitor();
if (this._sdTimer) { clearInterval(this._sdTimer); this._sdTimer = null; } if (this._sdTimer) { clearInterval(this._sdTimer); this._sdTimer = null; }
if (this._provisionMgr) { this._provisionMgr.stop(); this._provisionMgr = null; } if (this._provisionMgr) { this._provisionMgr.stop(); this._provisionMgr = null; }
this._frpc.stop(); this._frpc.stop();
@@ -151,6 +156,7 @@ class ClawClient {
this._hasEverConnected = true; // 标记已成功连接过 this._hasEverConnected = true; // 标记已成功连接过
this._sendConnect(); this._sendConnect();
this._startPing(); this._startPing();
this._startNetMonitor();
// 显示由 _onConnected 根据 status 设置,不在此处提前 showTime // 显示由 _onConnected 根据 status 设置,不在此处提前 showTime
}); });
@@ -169,6 +175,7 @@ class ClawClient {
ws.on('close', (code, reason) => { ws.on('close', (code, reason) => {
this._clearHeartbeat(); this._clearHeartbeat();
this._clearPing(); this._clearPing();
this._clearNetMonitor();
if (!this._stopped) { if (!this._stopped) {
this._wsFailCount++; this._wsFailCount++;
log.warn('clawd', `连接断开 (${code}),失败次数=${this._wsFailCount}${this._backoff / 1000}s 后重连...`); log.warn('clawd', `连接断开 (${code}),失败次数=${this._wsFailCount}${this._backoff / 1000}s 后重连...`);
@@ -216,6 +223,27 @@ class ClawClient {
this._awaitingPong = false; this._awaitingPong = false;
} }
// ── AP 模式网络监视(拔网线后 ≤5s 感知)────────────────────────────────────
_startNetMonitor() {
this._clearNetMonitor();
this._netMonitorTimer = setInterval(() => {
if (!this._provisionMgr || !this._provisionMgr.isApMode()) return;
if (hasInternet()) return;
// AP 模式 + 无网,但 WS 还"活着" → 立即终止,触发 close → _connect() 进入 5s 轮询
log.warn('clawd', 'AP 模式检测到网络断开,主动关闭 WS');
led.display.showAP();
if (this._ws) this._ws.terminate();
}, NET_MONITOR_MS);
}
_clearNetMonitor() {
if (this._netMonitorTimer) {
clearInterval(this._netMonitorTimer);
this._netMonitorTimer = null;
}
}
// ── 发送 connect ───────────────────────────────────────────────────────────── // ── 发送 connect ─────────────────────────────────────────────────────────────
_sendConnect() { _sendConnect() {