Android WebView应用WebSocket本地/公网IP自动切换及JS合并咨询
实现WebSocket本地/公网地址自动切换并合并JS逻辑
嘿,这个需求很实用!咱们可以通过先尝试本地连接,失败后自动 fallback 到公网地址的方式,把两个JS逻辑合并成一个,而且不用手动切换。下面是具体的实现方案:
核心思路
- 定义本地和公网两个WebSocket地址常量,方便后续维护
- 封装通用的连接函数,复用WebSocket的创建、事件绑定逻辑
- 优先尝试连接本地地址,若连接失败(或超时),自动切换到公网地址重试
- 加入失败重试限制,避免无限循环发起连接请求
完整合并后的JS代码
// 定义本地和公网WebSocket地址 const LOCAL_WS_URL = "ws://192.168.1.40:81/"; const PUBLIC_WS_URL = "ws://xxxxxx.ddns.net:81/"; let connection; let connectionAttempts = 0; const MAX_ATTEMPTS = 2; // 最多尝试本地+公网两次 // 通用WebSocket连接函数 function connectWebSocket(targetUrl) { console.log(`正在尝试连接: ${targetUrl}`); connection = new WebSocket(targetUrl); // 连接成功回调 connection.onopen = function () { console.log(`成功连接到 ${targetUrl}`); connection.send('Websocket funcionando!' + new Date()); connectionAttempts = 0; // 重置尝试次数 }; // 连接错误回调 connection.onerror = function (error) { console.log(`WebSocket 连接错误 (${targetUrl}):`, error); handleConnectionFailure(); }; // 意外关闭连接时触发切换 connection.onclose = function (event) { if (!event.wasClean) { console.log(`连接意外断开 (${targetUrl}),准备切换地址重试`); handleConnectionFailure(); } }; // 接收服务器消息回调 connection.onmessage = function (e) { console.log('Server:', e.data); }; // 超时检测:5秒内未成功连接则视为失败 setTimeout(() => { if (connection.readyState !== WebSocket.OPEN) { console.log(`连接超时 (${targetUrl})`); connection.close(); handleConnectionFailure(); } }, 5000); } // 处理连接失败后的逻辑 function handleConnectionFailure() { connectionAttempts++; if (connectionAttempts < MAX_ATTEMPTS) { // 第一次失败切换到公网,第二次失败可根据需求调整 const nextUrl = connectionAttempts === 1 ? PUBLIC_WS_URL : LOCAL_WS_URL; setTimeout(() => connectWebSocket(nextUrl), 1000); // 延迟1秒重试,避免频繁请求 } else { console.log("本地和公网连接均失败,请检查服务器状态或网络"); connectionAttempts = 0; // 重置次数,方便后续手动重试 } } // 初始化:优先尝试本地连接 connectWebSocket(LOCAL_WS_URL);
代码关键点解释
- 地址常量化:把两个地址抽成常量,后续修改时只需改一处,更易维护
- 逻辑复用:用通用连接函数封装重复的WebSocket创建、事件绑定代码,减少冗余
- 超时处理:添加5秒超时逻辑,避免连接一直处于pending状态无法触发切换
- 重试限制:最多尝试两次连接,防止无限循环请求服务器
- 状态重置:连接成功或全部失败后重置尝试次数,保证后续重试逻辑正常
额外优化建议
- 可以添加手动切换按钮,让用户在需要时强制切换地址:
// 手动切换到公网地址 function switchToPublic() { if (connection) connection.close(); connectionAttempts = 0; connectWebSocket(PUBLIC_WS_URL); } // 手动切换到本地地址 function switchToLocal() { if (connection) connection.close(); connectionAttempts = 0; connectWebSocket(LOCAL_WS_URL); } - 可以用
localStorage缓存上次成功连接的地址,下次初始化时优先使用,提升用户体验
内容的提问来源于stack exchange,提问作者Khales Naim




