IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Websocket心跳检测、重连机制 -> 正文阅读

[网络协议]Websocket心跳检测、重连机制

前言

为了获取实时数据,前端需要和后端保持通信,HTTP 协议只能是客户端向服务器发出请求,服务器返回查询结果。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。一般通过以下几种方式实现即时通讯。

即时通讯:短轮询、长链接、长轮询、websocket

短轮询的原理很简单,每隔一段时间客户端就发出一个请求,去获取服务器最新的数据, 一定程度上模拟实现了即时通讯。

优点:兼容性强,实现非常简单
缺点:延迟性高,非常消耗请求资源,影响性能

长轮询优缺点:

优点:兼容性好,资源浪费较小
缺点:服务器 hold连接会消耗资源,返回数据顺序无保证,难于管理维护

长连接优缺点:

优点:兼容性好,消息即时到达,不发无用请求
缺点:服务器维护长连接消耗资源

Websocket是一个全新的、独立的协议,基于 TCP协议,与 http协议兼容、却不会融入 http协议,仅仅作为 html5的一部分,其作用就是在服务器和客户端之间建立实时的双向 通信。

优点:真正意义上的实时双向通信,性能好,低延迟
缺点:独立与 http的协议,因此需要额外的项目改造,使用复杂度高,必须引入成熟的库,无法兼容低版本浏览器

轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,在更多的时候一般都会采用websocket来实现即时通讯的需求。

WebSocket心跳及重连机制

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

完整代码

创建websocket实例化的时候,一般会绑定各个回调事件需要执行的函数:

<html>
<head>
  <meta charset="utf-8">
  <title>WebSocket Demo</title>
</head>
<body>
  <script type="text/javascript">
    // var ws = new WebSocket("wss://echo.websocket.org");
    /*
    ws.onerror = function(e) {
      console.log('已关闭');
    };
    ws.onopen = function(e) {
      console.log('握手成功');
      ws.send('123456789');
    }
    ws.onclose = function() {
      console.log('已关闭');
    }
    ws.onmessage = function(e) {
      console.log('收到消息');
      console.log(e);
    }
    */
    
    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、第一步页面初始化,先调用createWebSocket函数,目的是创建一个websocket的方法:new WebSocket(wsUrl);因此封装成函数内如下代码:

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

2、第二步调用init方法,该方法内把一些监听事件封装如下:
当网络断开的时候,会先调用onerror,onclose事件可以监听到,会调用reconnect方法进行重连操作。正常的情况下,是先调用
onopen方法的,当接收到数据时,会被onmessage事件监听到。

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、重连操作 reconnect代码如下:
如果网络断开的话,会执行reconnect方法,使用了一个定时器,4秒后会重新创建一个新的websocket链接,重新调用createWebSocket函数,重新会执行及发送数据给服务器端。

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(){
      //这里发送一个心跳,后端收到后,返回一个心跳消息,
      //onmessage拿到返回的心跳就说明连接正常
      console.log('55555');
      ws.send("123456789");
      self.serverTimeoutObj = setTimeout(function() {
        console.log(111);
        console.log(ws);
        ws.close();
        // createWebSocket();
      }, self.timeout);

    }, this.timeout)
  }
}

更多文章__> >> 码砖猿的技术博客

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 22:34:38  更:2022-03-11 22:35:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:25:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码