You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android WebView应用WebSocket本地/公网IP自动切换及JS合并咨询

实现WebSocket本地/公网地址自动切换并合并JS逻辑

嘿,这个需求很实用!咱们可以通过先尝试本地连接,失败后自动 fallback 到公网地址的方式,把两个JS逻辑合并成一个,而且不用手动切换。下面是具体的实现方案:

核心思路

  1. 定义本地和公网两个WebSocket地址常量,方便后续维护
  2. 封装通用的连接函数,复用WebSocket的创建、事件绑定逻辑
  3. 优先尝试连接本地地址,若连接失败(或超时),自动切换到公网地址重试
  4. 加入失败重试限制,避免无限循环发起连接请求

完整合并后的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

火山引擎 最新活动