feat: AP always-on mode - hotspot stays until WiFi STA connects
Redesign provisioning from one-shot blocking to persistent background manager: - AP hotspot starts at boot regardless of eth0 status - Captive portal runs alongside AP for WiFi configuration - AP automatically shuts down only when WiFi STA connects - WiFi drops at runtime -> AP auto-restarts - WiFi connect fails -> AP auto-restarts for retry - client.js no longer blocks on network; connects WS when ready Made-with: Cursor
This commit is contained in:
@@ -7,7 +7,8 @@ const log = require('./logger');
|
||||
const { getBoxId } = require('./fingerprint');
|
||||
const { collect } = require('./metrics');
|
||||
const { getDashboardInfo, startTtyd, FrpcManager } = require('./frpc');
|
||||
const { ensureNetwork } = require('./provisioning');
|
||||
const { ProvisionManager } = require('./provisioning');
|
||||
const { hasInternet } = require('./network');
|
||||
|
||||
const MAX_BACKOFF_MS = 60_000;
|
||||
const PONG_TIMEOUT_MS = 15_000;
|
||||
@@ -59,12 +60,27 @@ class ClawClient {
|
||||
async start() {
|
||||
log.info('clawd', `启动中... 服务器 = ${this._cfg.server}`);
|
||||
|
||||
// 第一步:确保网络可用(无网时进入 AP 配网模式)
|
||||
await ensureNetwork({ clawId: this._cfg.claw_id });
|
||||
// 后台启动 AP 配网管理器(WiFi 未连接时常驻热点)
|
||||
this._provisionMgr = new ProvisionManager(this._cfg.claw_id);
|
||||
this._provisionMgr.start();
|
||||
|
||||
// 第二步:并行获取 dashboard 信息 + 启动 ttyd
|
||||
// 有网络时直接连接云端
|
||||
if (hasInternet()) {
|
||||
await this._proceedWithConnection();
|
||||
} else {
|
||||
// 等待配网完成后再连
|
||||
log.info('clawd', '等待网络就绪...');
|
||||
this._provisionMgr.once('network-ready', () => {
|
||||
this._proceedWithConnection().catch(e => {
|
||||
log.error('clawd', '连接启动失败:', e.message);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async _proceedWithConnection() {
|
||||
const [dashInfo] = await Promise.all([
|
||||
getDashboardInfo(),
|
||||
getDashboardInfo().catch(e => { log.warn('clawd', 'dashboard 信息获取失败:', e.message); return null; }),
|
||||
startTtyd().catch(e => log.warn('ttyd', '启动失败:', e.message)),
|
||||
]);
|
||||
this._dashInfo = dashInfo || {};
|
||||
@@ -77,6 +93,7 @@ class ClawClient {
|
||||
this._clearHeartbeat();
|
||||
this._clearPing();
|
||||
if (this._sdTimer) { clearInterval(this._sdTimer); this._sdTimer = null; }
|
||||
if (this._provisionMgr) { this._provisionMgr.stop(); this._provisionMgr = null; }
|
||||
this._frpc.stop();
|
||||
if (this._ws) this._ws.terminate();
|
||||
this._sdNotify('STOPPING=1');
|
||||
|
||||
Reference in New Issue
Block a user