diff --git a/src/lib/ws-client.js b/src/lib/ws-client.js index 4dd74ef..a5bf42c 100644 --- a/src/lib/ws-client.js +++ b/src/lib/ws-client.js @@ -45,6 +45,7 @@ export class WsClient { this._pingTimer = null this._challengeTimer = null this._wsId = 0 + this._autoPairAttempts = 0 } get connected() { return this._connected } @@ -65,6 +66,7 @@ export class WsClient { connect(host, token) { this._intentionalClose = false + this._autoPairAttempts = 0 this._token = token || '' this._url = `ws://${host}/ws?token=${encodeURIComponent(this._token)}` this._doConnect() @@ -86,6 +88,7 @@ export class WsClient { if (!this._url) return this._intentionalClose = false this._reconnectAttempts = 0 + this._autoPairAttempts = 0 this._stopPing() this._clearReconnectTimer() this._clearChallengeTimer() @@ -136,10 +139,14 @@ export class WsClient { return } if (e.code === 1008 && !this._intentionalClose) { - // origin not allowed — 自动写入 allowedOrigins 后再重连 - console.log('[ws] origin not allowed (1008),尝试自动修复...') - this._setConnected(false, 'reconnecting', 'origin not allowed,修复中...') - this._autoPairAndReconnect() + if (this._autoPairAttempts < 1) { + console.log('[ws] origin not allowed (1008),尝试自动修复...') + this._setConnected(false, 'reconnecting', 'origin not allowed,修复中...') + this._autoPairAndReconnect() + return + } + console.warn('[ws] origin 1008 自动修复已尝试过,显示错误') + this._setConnected(false, 'error', e.reason || 'origin not allowed,请点击「修复并重连」') return } this._setConnected(false) @@ -172,11 +179,14 @@ export class WsClient { const errCode = msg.error?.code console.error('[ws] connect 失败:', errMsg, errCode) - // 如果是配对/origin 错误,尝试自动配对 + // 如果是配对/origin 错误,尝试自动配对(仅一次,防止无限循环) if (errCode === 'NOT_PAIRED' || errCode === 'PAIRING_REQUIRED' || /origin not allowed/i.test(errMsg)) { - console.log('[ws] 检测到配对/origin 错误,尝试自动修复...', errCode || errMsg) - this._autoPairAndReconnect() - return + if (this._autoPairAttempts < 1) { + console.log('[ws] 检测到配对/origin 错误,尝试自动修复...', errCode || errMsg) + this._autoPairAndReconnect() + return + } + console.warn('[ws] 自动修复已尝试过,不再重试') } this._setConnected(false, 'error', errMsg) @@ -211,8 +221,9 @@ export class WsClient { } async _autoPairAndReconnect() { + this._autoPairAttempts++ try { - console.log('[ws] 检测到未配对,执行自动配对...') + console.log('[ws] 执行自动配对(第', this._autoPairAttempts, '次)...') const result = await api.autoPairDevice() console.log('[ws] 配对结果:', result) @@ -251,6 +262,7 @@ export class WsClient { } _handleConnectSuccess(payload) { + this._autoPairAttempts = 0 this._hello = payload || null this._snapshot = payload?.snapshot || null const defaults = this._snapshot?.sessionDefaults diff --git a/src/pages/chat-debug.js b/src/pages/chat-debug.js index 71ec9f7..7e2fcf4 100644 --- a/src/pages/chat-debug.js +++ b/src/pages/chat-debug.js @@ -463,9 +463,12 @@ function renderNetworkLog(contentEl) { async function fixPairing(page) { const logEl = page.querySelector('#ws-test-log') const contentEl = page.querySelector('#ws-log-content') + const fixBtn = page.querySelector('#btn-fix-pairing') + if (fixBtn) { fixBtn.disabled = true; fixBtn.textContent = '修复中...' } logEl.style.display = 'block' testLogs = [] + logEl.scrollIntoView({ behavior: 'smooth', block: 'start' }) function addLog(msg) { const timestamp = new Date().toLocaleTimeString('zh-CN', { hour12: false }) @@ -569,5 +572,7 @@ async function fixPairing(page) { } catch (e) { addLog(`❌ 修复失败: ${e}`) addLog('💡 建议:请手动前往"服务管理"页面重启 Gateway') + } finally { + if (fixBtn) { fixBtn.disabled = false; fixBtn.textContent = '一键修复配对' } } }