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 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在websocket
API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
为什么要有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 });复制代码
心跳检测机制检测服务器情况?
有了上面的了解接下来就要实现我这次需要时间的功能了
实例化一个
websocket
对象监听该对象的报错,发消息,异常信息
心跳检测机制,定时检测接口是否可以正常的返回,可以就继续操作,如有异常就关闭请求避免多次无用的请求。
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
链接的时候,
会触发
ws.onopen
心跳检测函数
heartCheck
heartCheck
给服务端发了请求,如果服务端是通常的,那么就会触发ws.onmessage
里面的heartCheck.start()
这次触发会清除掉两个定时器,内层定时器不会被触发了。如果没有在规定时间内返回讯息,那么就会出发内层定时器,连接关闭;连接关闭的时候,触发了
ws.onclose
里面的reconnect
函数,重新连接触发1,2,3的步骤
结束语
这只是我的业务需要,中间很多也是参考了前辈的文章才写出来的,websocket在实现实时数据这个方面还是很实用的。如果中间文章有任何问题欢迎评论区随时指正。
作者:一拳一个小朋友
链接:https://juejin.cn/post/7023637905629249543