fix(client): remove AP net monitor WS terminate (scheme A)
AP mode no longer periodically terminates WebSocket when hasInternet and hasWiredInternetProbe both fail; avoids false positives with hotspot + wired uplink. Reconnect and offline detection rely on Pong, peer close, and TCP. _connect() still defers new WS when AP and no uplink; close handler UI unchanged. Made-with: Cursor
This commit is contained in:
@@ -17,9 +17,6 @@ const MAX_BACKOFF_MS = 60_000;
|
|||||||
/** 连续若干轮 ping 后仍无 pong 才判定死链(单轮易因调度/弱网误判) */
|
/** 连续若干轮 ping 后仍无 pong 才判定死链(单轮易因调度/弱网误判) */
|
||||||
const PONG_MISS_MAX = 3;
|
const PONG_MISS_MAX = 3;
|
||||||
const PING_INTERVAL_MS = 15_000;
|
const PING_INTERVAL_MS = 15_000;
|
||||||
const NET_MONITOR_MS = 5_000; // AP 模式网络监视间隔
|
|
||||||
/** AP 下 nmcli/ping 易抖动:连续多轮无上行再关 WS,避免误杀仍通的长连接 */
|
|
||||||
const AP_NET_FAIL_MAX = 3;
|
|
||||||
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 秒)
|
||||||
|
|
||||||
@@ -43,10 +40,6 @@ class ClawClient {
|
|||||||
this._awaitingPong = false;
|
this._awaitingPong = false;
|
||||||
this._pongMissCount = 0;
|
this._pongMissCount = 0;
|
||||||
|
|
||||||
// AP 模式网络监视(WS 连通后每 5s 检查;连续多轮无上行才 terminate)
|
|
||||||
this._netMonitorTimer = null;
|
|
||||||
this._apNetFailStreak = 0;
|
|
||||||
|
|
||||||
// WS 连续失败计数(open 时清零)
|
// WS 连续失败计数(open 时清零)
|
||||||
this._wsFailCount = 0;
|
this._wsFailCount = 0;
|
||||||
// 是否曾经成功连接过(首次成功前不显示 Err0/AP)
|
// 是否曾经成功连接过(首次成功前不显示 Err0/AP)
|
||||||
@@ -171,7 +164,6 @@ 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._btMonitor) { this._btMonitor.stop(); this._btMonitor = null; }
|
if (this._btMonitor) { this._btMonitor.stop(); this._btMonitor = null; }
|
||||||
if (this._provisionMgr) { this._provisionMgr.stop(); this._provisionMgr = null; }
|
if (this._provisionMgr) { this._provisionMgr.stop(); this._provisionMgr = null; }
|
||||||
@@ -212,7 +204,6 @@ class ClawClient {
|
|||||||
this._hasEverConnected = true; // 标记已成功连接过
|
this._hasEverConnected = true; // 标记已成功连接过
|
||||||
this._sendConnect();
|
this._sendConnect();
|
||||||
this._startPing();
|
this._startPing();
|
||||||
this._startNetMonitor();
|
|
||||||
// 显示由 _onConnected 根据 status 设置,不在此处提前 showTime
|
// 显示由 _onConnected 根据 status 设置,不在此处提前 showTime
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -232,7 +223,6 @@ 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 后重连...`);
|
||||||
@@ -297,40 +287,6 @@ class ClawClient {
|
|||||||
this._pongMissCount = 0;
|
this._pongMissCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── AP 模式网络监视(拔网线后 ≤5s 感知)────────────────────────────────────
|
|
||||||
|
|
||||||
_startNetMonitor() {
|
|
||||||
this._clearNetMonitor();
|
|
||||||
this._apNetFailStreak = 0;
|
|
||||||
this._netMonitorTimer = setInterval(() => {
|
|
||||||
if (!this._provisionMgr || !this._provisionMgr.isApMode()) {
|
|
||||||
this._apNetFailStreak = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (hasInternet() || hasWiredInternetProbe()) {
|
|
||||||
this._apNetFailStreak = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._apNetFailStreak++;
|
|
||||||
if (this._apNetFailStreak < AP_NET_FAIL_MAX) {
|
|
||||||
log.info('clawd', `AP 网监:无上行 (${this._apNetFailStreak}/${AP_NET_FAIL_MAX}),累计后再判定`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
log.warn('clawd', 'AP 模式检测到网络断开(已连续多次无上行),主动关闭 WS');
|
|
||||||
led.display.showAP();
|
|
||||||
this._apNetFailStreak = 0;
|
|
||||||
if (this._ws) this._ws.terminate();
|
|
||||||
}, NET_MONITOR_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
_clearNetMonitor() {
|
|
||||||
if (this._netMonitorTimer) {
|
|
||||||
clearInterval(this._netMonitorTimer);
|
|
||||||
this._netMonitorTimer = null;
|
|
||||||
}
|
|
||||||
this._apNetFailStreak = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── 发送 connect ─────────────────────────────────────────────────────────────
|
// ── 发送 connect ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
_sendConnect() {
|
_sendConnect() {
|
||||||
|
|||||||
Reference in New Issue
Block a user