两年前写了一篇websocket心跳的博客——初探和实现websocket心跳重连。 阅读量一直比较大,加上最近考虑写一个本身的npm包,所以就完成了一个websocket心跳的检测库。在这里先感谢几个提供帮助的大佬朋友们,小弟受益不浅。html
websocket-heartbeat-js基于浏览器js原生websocket封装,主要目的是保障客户端websocket与服务端链接状态。该程序有心跳检测及自动重连机制,当网络断开或者后端服务问题形成客户端websocket断开,程序会自动尝试从新链接直到再次链接成功。前端
在使用原生websocket的时候,若是设备网络断开,不会触发任何函数,前端程序没法得知当前链接已经断开。这个时候若是调用websocket.send方法,浏览器就会发现消息发不出去,便会马上或者必定短期后(不一样浏览器或者浏览器版本可能表现不一样)触发onclose函数。node
后端websocket服务也可能出现异常,链接断开后前端也并无收到通知,所以须要前端定时发送心跳消息ping,后端收到ping类型的消息,立马返回pong消息,告知前端链接正常。若是必定时间没收到pong消息,就说明链接不正常,前端便会执行重连。git
为了解决以上两个问题,之前端做为主动方,定时发送ping消息,用于检测网络和先后端链接问题。一旦发现异常,前端持续执行重连逻辑,直到重连成功。github
1.关闭websocket链接web
若是须要断开websocket,应该执行WebsocketHeartbeatJs.close(),WebsocketHeartbeatJs.ws是原生Websocket实例对象,WebsocketHeartbeatJs.ws.onclose,已经被绑定了重连方法,若是后端websocket服务直接关闭链接,前端WebsocketHeartbeatJs.ws.onclose会被执行,WebsocketHeartbeatJs会尝试重连。若是后端想告诉前端须要断开链接,须要发送特定消息给前端,前端收到特定消息,调用WebsocketHeartbeatJs.close(),WebsocketHeartbeatJs将不会重连。npm
websocketHeartbeatJs.onmessage = (e) => { if(e.data == 'close') websocketHeartbeatJs.close(); }
2.ping & pongjson
前端发送ping消息,后端收到后,须要马上返回pong消息,pong消息能够是任何值,websocket-heartbeat-js并不处理pong消息,而只是在收到任何消息后,重置心跳,由于收到任何消息就说明链接是正常的。后端
npm install websocket-heartbeat-js
import WebsocketHeartbeatJs from 'websocket-heartbeat-js'; let websocketHeartbeatJs = new WebsocketHeartbeatJs({ url: 'ws://xxxxxxx' }); websocketHeartbeatJs.onopen = function () { console.log('connect success'); websocketHeartbeatJs.send('hello server'); } websocketHeartbeatJs.onmessage = function (e) { console.log(`onmessage: ${e.data}`); } websocketHeartbeatJs.onreconnect = function () { console.log('reconnecting...'); }
<script src="./node_modules/websocket-heartbeat-js/dist/index.js"></script> let websocketHeartbeatJs = new window.WebsocketHeartbeatJs({ url: 'ws://xxxxxxx' });
websocket-heartbeat-js仅仅是封装了心跳相关的钩子函数,websocketHeartbeatJs.ws是原生Websocket实例,如须要使用更多websocket特性,请直接操做websocketHeartbeatJs.ws。api
websocketHeartbeatJs.ws 等于 WebSocket(websocketHeartbeatJs.opts.url);
属性 | 必填 | 类型 | 默认值 | 描述 |
---|---|---|---|---|
url | true | string | none | websocket服务端接口地址 |
pingTimeout | false | number | 15000 | 每隔15秒发送一次心跳,若是收到任何后端消息定时器将会重置 |
pongTimeout | false | number | 10000 | ping消息发送以后,10秒内没收到后端消息便会认为链接断开 |
reconnectTimeout | false | number | 2000 | 尝试重连的间隔时间 |
pingMsg | false | string | "heartbeat" | ping消息值 |
const options = { url: 'ws://xxxx', pingTimeout: 15000, pongTimeout: 10000, reconnectTimeout: 2000, pingMsg: "heartbeat" } let websocketHeartbeatJs = new WebsocketHeartbeatJs(options);
发送消息给后端
websocketHeartbeatJs.send('hello server');
前端手动断开websocket链接,此方法不会触发重连。 websocketHeartbeatJs.close()
websocketHeartbeatJs.onclose = () => { console.log('connect close'); }
websocketHeartbeatJs.onerror = () => { console.log('connect onerror'); }
websocketHeartbeatJs.onopen = () => { console.log('open success'); }
websocketHeartbeatJs.onmessage = (e) => { console.log('msg:', e.data); }
websocketHeartbeatJs.onreconnect = (e) => { console.log('reconnecting...'); }