一篇文章带你创建快速稳定的WebSocket长链接

        在一个完善的即时信息应用中,WebSocket是极其关键的一环,它为基于Web的即时通讯应用提供了一种全双工的通信机制。但为了提升实际应用场景下的消息即时性和可靠性,我们需要克服WebSocket及其底层依赖的TCP连接对于复杂网络情况下的不稳定性,即时通讯的开发者们通常都需要为其设计一套完整的连接保活、验活以及断片网重连方案。就断网重连而言,其重连响应速度将严重影响了上层应用的“即时性”和用户体验。

        因此,如何在复杂网络场景下,更即时快速地感知网络变动,并快速恢复WebSocket的可用性,就变得尤为重要。本文分享WebSocket在不同状态下、不同的网络状态下,应该如何实现快速断网重连。

1. WebSocket长链接的基本使用

// 定义几个变量检测状态
var WS_URL = "ws://127.0.0.1:9225/ws";  // websocket地址 http对应ws https对应wss
var timeout = 30*1000; // 心跳检测时间
var timeoutObj = null; // 心跳心跳倒计时
var serverTimeoutObj = null; // 心跳倒计时
var lockReconnect = false; // 防止
var timeoutnum = null; // 断开重连倒计时

// 创建websocket
function initWebSocket(){
    // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
    window.websocket = new WebSocket(WS_URL);
    // websocket链接成功回调
    window.websocket.onopen = websocketonopen;
    // websocket链接发生错误回调
    window.websocket.onerror = websocketonerror;
    // websocket链接获取到消息调用注册全局websocket消息接收事件
    window.websocket.onmessage = websocketonmessage;
    // websocket断开消息回调
    window.websocket.onclose = websocketonclose;
}

// onopen回调函数
function websocketonopen() {
    // 连接成功后开启心跳
    heart();
    console.log("WebSocket连接成功!!!" + new Date() + "----" + window.websocket.readyState);
}

// onerror回调函数
function websocketonerror(e) {
    // 如果发生链接错误 则关闭websocket
    closeWebSocket()
    console.log("WebSocket连接发生错误,重启socket");
    console.log('Error:',e)
}

// onclose回调函数
function websocketonclose(e) {
    window.websocket.close();
    clearTimeout(timeoutObj);
    clearTimeout(serverTimeoutObj);
    console.log("WebSocket连接关闭,重启socket");
    // 链接关闭,执行重新连接
    reconnect();
}

// onmessage回调函数
function websocketonmessage(event) {
    // 重置心跳检测 
    reset();
    // 自定义全局监听事件
    window.dispatchEvent(
        new CustomEvent("onWebSocketMessage", {
            detail: {
                data: event.data,
            },
        })
    );
}

// 关闭WebSocket
function closeWebSocket() {
    // 关闭websocket
    window.websocket.close();
}

2. WebSocket使用心跳检测和断开重新连接

为什么使用心跳检测?

因为WebSocket底层基于tcp连接,所以在有些时候是无法触发onclose函数来感知WebSocket链接已经断开的,例如:切换网络、链路中间路由崩溃、链路的前端出口不可用、服务器负载持续过高无法响应;导致链接断开的原因有很多难以把控,所以通过心跳检测的方式定时向服务端发送消息,服务端返回心跳检测消息,前端根据消息判断是否出现err,如果出现err则说明连接断开,进行重新连接,通过这样可以保证链接的;

// 心跳检测函数
function heart(){
    //清除延时器
    timeoutObj && clearTimeout(timeoutObj);
    serverTimeoutObj && clearTimeout(serverTimeoutObj);
    timeoutObj = setTimeout(() => {
        if (window.websocket && window.websocket.readyState == 1) {
            //发送消息,服务端返回信息,即表示连接良好,可以在socket的onmessage事件重置心跳机制函数
            window.websocket.send("heart");
        } else {
            //如果不返回消息 则执行WebSocket重连
            reconnect();
        }

        //定义一个延时器等待服务器响应,若超时,则关闭连接,重新请求server建立socket连接
        serverTimeoutObj = setTimeout(() => {
            window.websocket.close();
        }, timeout);
    }, timeout);
}

// 收到消息后重新执行心跳检测
function reset() {
    // 重置心跳 清除时间
    clearTimeout(timeoutObj);
    clearTimeout(serverTimeoutObj);
    // 重启心跳
    heart();
}
// 重连接函数
function reconnect(){
    if (lockReconnect) return;
    lockReconnect = true;
    //没连接上会一直重连,设置延迟避免请求过多
    timeoutnum && clearTimeout(timeoutnum);
    timeoutnum = setTimeout(() => {
        initWebSocket();
        lockReconnect = false;
    }, 5000);
}

3. 监测电脑网络状态,实现断开快速重新连接 

javascript通过监听online和offline事件判断网络状态

心跳检测的弊端在于定时发送请求,即时性不够。通过网络状态监测可以更快感知断开,弥补心跳检测的缺点,使链接更快速,系统更稳定

// 监听网络状态
window.addEventListener("online", () => {
    console.log("网络正常");
});

window.addEventListener("offline", () => {
    console.log("网络断开");
    // 网络断开则重连
    reconnect()
});

4. 注册全局WebSocket监听事件,保证在模块化开发中任何地方都能用到同一个WebSocket,不用重新创建连接。

// onmessage回调函数
function websocketonmessage(event) {
    // 重置心跳检测 
    reset();
    // 自定义全局监听事件
    window.dispatchEvent(
        new CustomEvent("onWebSocketMessage", {
            detail: {
                data: event.data,
            },
        })
    );
}

// 全局可以监听websocket onmessage事件
window.addEventListener("onWebSocketMessage", businessFunction);

// 获取到websocket返回执行业务代码
function businessFunction(data){
    console.log("Data::::",data)
}

 5. 免费完整代码包下载,拿来即用。

免费资源下载地址:

https://download.csdn.net/download/qq_41765777/88599368icon-default.png?t=N7T8https://download.csdn.net/download/qq_41765777/88599368

6. WebSocket测试工具

websocket在线测试WebSocket 在线测试 工具 物联网icon-default.png?t=N7T8http://www.websocket-test.com/

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在Java中,你可以使用Java API for WebSocket(JSR 356)来创建WebSocket连接。下面是一个简单的示例代码,展示了如何在Java中创建WebSocket连接: ```java import javax.websocket.ClientEndpoint; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.WebSocketContainer; import java.net.URI; @ClientEndpoint public class WebSocketClient { @OnOpen public void onOpen(Session session) { System.out.println("WebSocket连接已打开: " + session.getId()); } @OnMessage public void onMessage(String message, Session session) { System.out.println("收到消息: " + message); } public static void main(String[] args) { WebSocketContainer container = javax.websocket.ContainerProvider.getWebSocketContainer(); String uri = "ws://example.com/websocket"; // 替换成实际的WebSocket服务器地址 try { Session session = container.connectToServer(WebSocketClient.class, URI.create(uri)); session.getBasicRemote().sendText("Hello, WebSocket!"); } catch (Exception e) { e.printStackTrace(); } } } ``` 以上代码定义了一个`WebSocketClient`类,并使用`@ClientEndpoint`注解标记为WebSocket客户端端点。`@OnOpen`和`@OnMessage`注解用于处理WebSocket连接的打开和接收消息的事件。 在`main`方法中,我们获取一个`WebSocketContainer`实例,然后使用`connectToServer`方法连接到指定的WebSocket服务器。你需要将`uri`替换为实际的WebSocket服务器地址。 通过运行以上代码,你将能够创建一个WebSocket连接,并在连接打开后发送一条消息。你可以根据需要添加其他事件处理方法或自定义消息处理逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进阶的疯狗der

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值