Strophe.js切换WiFi进入DISCONNECTED状态后无法自动重连求助
嘿,这个问题我之前帮不少开发者解决过——Strophe.js在网络切换时触发DISCONNECTED是很常见的场景,毕竟WiFi切换会导致TCP连接中断。咱们来一步步实现可靠的自动重连机制,保证用户体验不打折扣。
1. 基础:监听断开事件,区分主动/被动断开
首先,你需要在Strophe的连接状态回调里处理DISCONNECTED状态,但要注意区分用户主动断开和网络被动断开,避免主动退出时还触发重连。
先定义几个全局变量保存连接实例和重连状态:
let xmppConnection; let reconnectTimeout; const MAX_RECONNECT_TRIES = 5; // 最大重连次数 let currentReconnectAttempt = 0; let isManualDisconnect = false; // 标记是否是主动断开
然后初始化连接并处理状态回调:
function initXMPPConnection(jid, password) { // 替换成你的BOSH端点地址 xmppConnection = new Strophe.Connection('https://your-xmpp-server.com/http-bind/'); // 连接回调 xmppConnection.connect(jid, password, (status) => { switch(status) { case Strophe.Status.CONNECTED: console.log('✅ XMPP连接成功'); currentReconnectAttempt = 0; // 重连成功后重置次数 // 这里可以恢复会话:比如发送在线状态、重新订阅联系人 xmppConnection.send($pres()); break; case Strophe.Status.DISCONNECTED: if (isManualDisconnect) { console.log('🔌 用户主动断开连接'); isManualDisconnect = false; // 重置标记 return; } // 被动断开,触发重连逻辑 attemptReconnect(jid, password); break; case Strophe.Status.CONNFAIL: case Strophe.Status.AUTHFAIL: console.log('⚠️ 连接/认证失败,尝试重连'); attemptReconnect(jid, password); break; // 其他状态(比如连接中、认证中)按需处理 default: console.log(`连接状态:${status}`); } }); } // 手动断开函数(用户退出时调用) function disconnectManually() { isManualDisconnect = true; xmppConnection.disconnect(); }
2. 实现指数退避重连
直接频繁重试会给服务器和客户端都造成压力,最好用指数退避策略——每次重连的等待时间翻倍,直到达到最大重试次数。
function attemptReconnect(jid, password) { if (currentReconnectAttempt >= MAX_RECONNECT_TRIES) { console.log('❌ 重连次数已达上限,请检查网络后手动重试'); // 这里可以给用户显示提示,比如弹出对话框 return; } // 计算延迟:1s → 2s → 4s → 8s → 16s const delay = Math.pow(2, currentReconnectAttempt) * 1000; console.log(`⏳ 即将在${delay/1000}秒后尝试第${currentReconnectAttempt+1}次重连`); reconnectTimeout = setTimeout(() => { currentReconnectAttempt++; xmppConnection.connect(jid, password, (status) => { // 复用之前的状态回调逻辑 initXMPPConnection(jid, password); }); }, delay); }
3. 优化:监听浏览器网络状态
除了Strophe的断开事件,还可以监听浏览器的online/offline事件,在网络恢复时立即触发重连,不用等到超时。
// 监听网络恢复 window.addEventListener('online', () => { console.log('🌐 网络已恢复,立即尝试重连'); if (xmppConnection && !xmppConnection.connected) { clearTimeout(reconnectTimeout); // 清除之前的超时任务 currentReconnectAttempt = 0; // 直接触发重连(注意提前保存用户的JID和密码) initXMPPConnection(savedJid, savedPassword); } }); // 监听网络断开 window.addEventListener('offline', () => { console.log('🌐 网络已断开'); // 这里可以给用户显示网络断开的提示 });
4. 额外注意事项
- 保存用户凭证:重连时需要用到JID和密码,建议在登录成功后安全地保存(比如用
sessionStorage,不要存明文密码,最好用服务器颁发的token)。 - 恢复会话状态:重连成功后,记得重新发送在线状态、订阅联系人、恢复之前的聊天窗口等,让用户感觉不到断连。
- 用户提示:在重连过程中给用户显示状态(比如“正在重连...”),避免用户误以为应用卡死。
内容的提问来源于stack exchange,提问作者kumaran
相关产品推荐
相关产品推荐

