问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

WebSocket Demo

创作时间:
作者:
@小白创作中心

WebSocket Demo

引用
CSDN
1.
https://blog.csdn.net/m0_64227118/article/details/136193952

WebSocket是一种在单个TCP连接上进行全双工通信的协议,它使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在传统的HTTP协议中,客户端向服务器发出请求,服务器返回查询结果,这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。而WebSocket则可以解决这个问题,它可以在客户端和服务器之间建立一个持久的连接,实现双向通信。

WebSocket心跳及重连机制

WebSocket是前后端交互的长连接,在使用的过程中,遇到弱网或者网络暂时断连的情况时,服务端并没有触发onclose的事件,客户端也无法得知当前连接是否已经断开,服务端会继续向客户端发送多余链接,并且这些数据还会丢失。因此为了保证连接的可持续性和稳定性,我们需要有一套机制来检测客户端和服务端是否处于正常连接状态,WebSocket心跳重连就应运而生。

基本使用

WebSocket的基本使用方法可以参考WebSocket API。下面是一些关键方法和属性的介绍:

连接建立

ws.onopen = function () {
  ws.send('Hello Server!');
}

如果要指定多个回调函数,可以使用addEventListener方法:

ws.addEventListener('open', function (event) {
  ws.send('Hello Server!');
});

连接状态

WebSocket实例对象的readyState属性返回当前状态,共有四种:

  • CONNECTING:值为0,表示正在连接。
  • OPEN:值为1,表示连接成功,可以通信了。
  • CLOSING:值为2,表示连接正在关闭。
  • CLOSED:值为3,表示连接已经关闭,或者打开连接失败。

错误处理

实例对象的onerror属性,用于指定报错时的回调函数。

连接关闭

实例对象的onclose属性,用于指定连接关闭后的回调函数。

数据接收

实例对象的onmessage属性,用于指定接收到消息时的回调函数。

数据发送

实例对象的send()方法用于向服务器发送数据。

发送缓冲

实例对象的bufferedAmount属性,表示还有多少字节的二进制数据没有发送出去。它可以用来判断发送是否结束。

完整代码实现

下面是一个完整的WebSocket使用示例,包含了心跳检测和断线重连机制:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>WebSocket Demo</title>
</head>
<body>
  <script type="text/javascript">
    var lockReconnect = false; // 避免重复连接
    var wsUrl = "wss://echo.websocket.org";
    var ws;
    var tt;

    function createWebSocket() {
      try {
        ws = new WebSocket(wsUrl);
        init();
      } catch(e) {
        console.log('catch');
        reconnect(wsUrl);
      }
    }

    function init() {
      ws.onclose = function () {
        console.log('链接关闭');
        reconnect(wsUrl);
      };
      ws.onerror = function() {
        console.log('发生异常了');
        reconnect(wsUrl);
      };
      ws.onopen = function () {
        // 心跳检测重置
        heartCheck.start();
      };
      ws.onmessage = function (event) {
        // 拿到任何消息都说明当前连接是正常的
        console.log('接收到消息');
        heartCheck.start();
      }
    }

    function reconnect(url) {
      if(lockReconnect) {
        return;
      };
      lockReconnect = true;
      // 没连接上会一直重连,设置延迟避免请求过多
      tt && clearTimeout(tt);
      tt = setTimeout(function () {
        createWebSocket(url);
        lockReconnect = false;
      }, 4000);
    }

    // 心跳检测
    var heartCheck = {
      timeout: 3000,
      timeoutObj: null,
      serverTimeoutObj: null,
      start: function(){
        console.log('start');
        var self = this;
        this.timeoutObj && clearTimeout(this.timeoutObj);
        this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
        this.timeoutObj = setTimeout(function(){
          // 这里发送一个心跳,后端收到后,返回一个心跳消息,
          console.log('55555');
          ws.send("123456789");
          self.serverTimeoutObj = setTimeout(function() {
            console.log(111);
            console.log(ws);
            ws.close();
            // createWebSocket();
          }, self.timeout);
        }, this.timeout)
      }
    }

    createWebSocket(wsUrl);
  </script>
</body>
</html>

具体步骤

  1. 创建WebSocket连接

    function createWebSocket() {
      try {
        ws = new WebSocket(wsUrl);
        init();
      } catch(e) {
        console.log('catch');
        reconnect(wsUrl);
      }
    }
    
  2. 初始化监听事件

    function init() {
      ws.onclose = function () {
        console.log('链接关闭');
        reconnect(wsUrl);
      };
      ws.onerror = function() {
        console.log('发生异常了');
        reconnect(wsUrl);
      };
      ws.onopen = function () {
        // 心跳检测重置
        heartCheck.start();
      };
      ws.onmessage = function (event) {
        // 拿到任何消息都说明当前连接是正常的
        console.log('接收到消息');
        heartCheck.start();
      }
    }
    
  3. 重连操作

    var lockReconnect = false; // 避免重复连接
    function reconnect(url) {
      if(lockReconnect) {
        return;
      };
      lockReconnect = true;
      // 没连接上会一直重连,设置延迟避免请求过多
      tt && clearTimeout(tt);
      tt = setTimeout(function () {
        createWebSocket(url);
        lockReconnect = false;
      }, 4000);
    }
    
  4. 心跳检测

    // 心跳检测
    var heartCheck = {
      timeout: 3000,
      timeoutObj: null,
      serverTimeoutObj: null,
      start: function(){
        console.log('start');
        var self = this;
        this.timeoutObj && clearTimeout(this.timeoutObj);
        this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
        this.timeoutObj = setTimeout(function(){
          // 这里发送一个心跳,后端收到后,返回一个心跳消息,
          console.log('55555');
          ws.send("123456789");
          self.serverTimeoutObj = setTimeout(function() {
            console.log(111);
            console.log(ws);
            ws.close();
            // createWebSocket();
          }, self.timeout);
        }, this.timeout)
      }
    }
    

通过以上步骤,我们可以实现一个完整的WebSocket连接,包括心跳检测和断线重连机制,确保WebSocket连接的稳定性和可靠性。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号