function reconnect(url) {
setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多
var ws = new WebSocket(url);
ws.onclose = function () {
reconnect()
ws.onerror = function () {
reconnect()
}, 2000);
稍微抽取再丰富下,createWebSocket来创建
websocket实例
,initEventHandle来绑定各回调函数:
var ws = new WebSocket(url);
ws.onclose = function () {
reconnect()
ws.onerror = function () {
reconnect()
// 重连
function reconnect(url) {
setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多
createWebSocket(url);
}, 2000);
// 实例websocket
function createWebSocket(url) {
try {
if ('WebSocket' in window) {
ws = new WebSocket(url);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket(url);
} else {
_alert("当前浏览器不支持websocket协议,建议使用现代浏览器",3000)
initEventHandle();
} catch (e) {
reconnect(url);
// 初始化事件函数
function initEventHandle() {
ws.onclose = function () {
reconnect(wsUrl);
ws.onerror = function (err) {
reconnect(wsUrl);
弱网、断连所导致重连都是被动的,而在一般的websocket连接中都是存在心跳机制的,客户端和服务端约定一个特定的心跳消息用于检测链路是否通信正常。
我们通过心跳机制,在客户端来检测链路的正常,在约定时间间隔内收不到心跳或者其他任何通信消息时,客户端进行主动重连。
所以下面优化的,我们需要加一个心跳检测的方法:
var heartCheck = {
timeout: heartBeatTime*1000, // 心跳检测时长
timeoutObj: null, // 定时变量
reset: function () { // 重置定时
clearTimeout(this.timeoutObj);
return this;
start: function () { // 开启定时
var self = this;
this.timeoutObj = setTimeout(function () {
// 心跳时间内收不到消息,主动触发连接关闭,开始重连
ws.close();
},this.timeout)
心跳检测对象,定义了
- timeout:心跳超时时间
- timeoutObj:定时器变量
- reset:重置心跳
- start:开启心跳
当连接成功时,开启心跳;在收到消息时,重置心跳并开启下一轮检测,所以我们只需要在onopen和onmessage中加入心跳检测就行
// 初始化事件函数
function initEventHandle() {
ws.onclose = function () {
reconnect(wsUrl);
ws.onerror = function (err) {
reconnect(wsUrl);
ws.onopen = function () {
heartCheck.reset().start(); //心跳检测重置
ws.onmessage = function (msg) { //如果获取到消息,心跳检测重置
heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的
handleMsg(msg)
同时触发多次重连的问题
在实际使用过程中,发现有些浏览器,reconnect重连会多次触发,所以需要给重连加一把锁,当一个重连正在执行的时候,无法再触发一次重连
function reconnect(url) {
if (reconnect.lockReconnect) return;
reconnect.lockReconnect = true;
setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多
createWebSocket(url);
reconnect.lockReconnect = false;
}, 2000);
如果是同个浏览器中多个页面共用一个连接来进行通信,那么就需要使用浏览器缓存/数据路(localStorage/indexedDB)去加这把锁。
我这里在分享一篇微信小程序websocket心跳重连机制的实现方式:微信小程序websocket重连机制实现
作者:loosenRogers
链接:https://www.jianshu.com/p/5297732db7f2