阅读 2059

websocket以及心跳检测机制

以及心跳检测机制

最近的一个项目需要用到 websocket 来实现实时数据的展示,之前的项目基本上没有这个需求所以自己对于 websocket 基本是一知半解的状态。要求当服务器挂起的时候能够检测到挂起中断请求,当服务器正常的时候,要及时连接,因为之前已经有很多前辈的文章对这个有过很详细的论述了,所以我只记录了自己需要学习的地方,本文章不适合作为学习websocket的教程,如果有想要详细的学习websocket教程的请移步阮一峰大神博客,他写的比较详细websocket 教程。

websocket简介

  • 什么是websocket?

  • 为什么要有websocket?

  • 怎么使用websocket?

  • 心跳检测机制间歇性校测服务器情况?

什么是websocket?

WebSocket 是一种网络通信协议,更完整的解释是一种基于 TCP 的全双工通信协议,是不是感觉好像解释了又好像没有,WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 通信协议于 2011 年被 IETF 定为标准 RFC 6455,并由 RFC7936 补充规范。WebSocket API 也被 W3C 定为标准。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在websocketAPI 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

为什么要有websocket?

很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每 1 秒),由浏览器对服务器发出 HTTP 请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而 HTTP 请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

http 还有一个比较明显的缺陷就是只能由客户端发起也就是说,如果我想要知道一条结果只能由客户端发起请求,然后服务端返回请求,做不到服务端自动的向客户端推送数据。

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。

轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,工程师们一直在思考,有没有更好的方法。websocket就是这样发明的。 而比较新的技术去做轮询的效果是 Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在 Comet 中,普遍采用的长链接,也会消耗服务器资源。 在这种情况下,HTML5 定义了websocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

websocket 的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

怎么使用websocket?

通过上面的阐述我们大致了解到了为什么要有websocket以及什么是websocket,下面就让我们看一下,我们再代码里面应该怎么去使用websocket

实例化websocket

var ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};复制代码

websocket相关的API

  • websocket的构造函数

WebSocket 对象作为一个构造函数,
用于新建 WebSocket 实例
var ws = new WebSocket(url);复制代码
  • 实例对象的onopen属性,用于指定连接成功后的回调函数

ws.onopen = function () {
  ws.send('Hello Server!');
}复制代码
  • 实例对象的onclose属性,用于指定连接关闭后的回调函数。

ws.onclose = function(event) {
  var code = event.code;
  var reason = event.reason;
  var wasClean = event.wasClean;
  // handle close event
};

ws.addEventListener("close", function(event) {
  var code = event.code;
  var reason = event.reason;
  var wasClean = event.wasClean;
  // handle close event
});复制代码
  • 实例对象的onmessage属性,用于指定收到服务器数据后的回调函数。

ws.onmessage = function(event) {
  var data = event.data;
  // 处理数据
};

ws.addEventListener("message", function(event) {
  var data = event.data;
  // 处理数据
});复制代码
  • 实例对象的send()方法用于向服务器发送数据。

ws.send('your message');复制代码
  • 实例对象的onerror属性,用于指定报错时的回调函数。

socket.onerror = function(event) {
  // handle error event
};

socket.addEventListener("error", function(event) {
  // handle error event
});复制代码

心跳检测机制检测服务器情况?

有了上面的了解接下来就要实现我这次需要时间的功能了

  1. 实例化一个websocket对象

  2. 监听该对象的报错,发消息,异常信息

  3. 心跳检测机制,定时检测接口是否可以正常的返回,可以就继续操作,如有异常就关闭请求避免多次无用的请求。

var ws;
var tt;
var lockReconnnet=false;
var wxUrl='https://api/v1/1';
function createWebSocket(url){
  try{
  ws=new WebSocket(url);
  init();
  }catch(){
  reconnect(url);
  }
}
function init(){
  ws.onclose=function(){
    console.log("websocket关闭了");
    reconnect(url);
  }
  ws.onopen=function(){
    console.log("websocket打开了");
    heartCheck(url);
  }
  ws.onerror=function(){
    console.log("websocket报错了");
    reconnect(url);
  }
  ws.onmessage=function(){
    //能收到消息说明链接正常
    heartCheck(url);
  }
}
function reconnect(url){
//如果连接被锁定了,就说明当前的链接是正常的
  if(lockReconnnet){
    return;
  }
  lockReconnnet=true;
  //清除定时器
  tt&&clearTimeOut(tt);
  tt=setTimeOut(()=>{
   createWebSocket(url);
   lockReconnnet=false;
  },4000)
}
var heartCheck={
   timeout:3000,
   timeOutObj:null,
   serverTimeOutObj:null,
   start:function(){
     var self=this;
     this.timeOutObj&&clearTimeOut(this.timeOutObj);
     this.serverTimeOutObj&&clearTimeOut(this.serverTimeOutObj)
     this.timeOutObj=setTimeOut(()=>{
        ws.send("发送数据");
        self.serverTimeOutObj=setTimeOut(()=>{
          ws.onclose();
        },self.timeout)
     },self.timeout)
   }
}
createWebSocket(wsUrl);复制代码

当创建webSocket链接的时候,

  1. 会触发ws.onopen

  2. 心跳检测函数heartCheck

  3. heartCheck给服务端发了请求,如果服务端是通常的,那么就会触发ws.onmessage里面的 heartCheck.start()这次触发会清除掉两个定时器,内层定时器不会被触发了。如果没有在规定时间内返回讯息,那么就会出发内层定时器,连接关闭;

  4. 连接关闭的时候,触发了ws.onclose里面的reconnect函数,重新连接触发1,2,3的步骤

结束语

这只是我的业务需要,中间很多也是参考了前辈的文章才写出来的,websocket在实现实时数据这个方面还是很实用的。如果中间文章有任何问题欢迎评论区随时指正。


作者:一拳一个小朋友
链接:https://juejin.cn/post/7023637905629249543


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐