websocket 封装(含心跳,重连机制,强制退出)
/**
* @param {JSON} json 连接建立立即发送,如果想不发送就传' ',
* @param {String} url
* @param {Function} callback 接收服务端数据时触发的回调
* @param {Object} protocol 第二个参数 protocol 是可选的,指定了可接受的子协议。
*/
const WS = function (json, url, callback, protocol) {
this.json = json;
this.url = url;
this.protocol = typeof (protocol) == 'undefined' ? null : protocol || ''
this.reconnect_time = 0; //重连的时间
this.reconnect_count = 0; //重连次数
this.is_destroy = false //强制关闭
this.is_reconnect = false; // 是否重连过
this.last_health_time = -1; //上一次心跳时间
this.keep_alive_timer; //心跳定时发送
this.reconnect_timer; // 重连操作
this.socket; //socket对象
this.initWs();
this.onopen = e => {
if (this.socket) {
this.socket.send(json);
this.reconnect_count = 0; //重连上把重连次数清空
this.reconnect_time = 0; //重连的时间清空
if (this.socket.readyState === 1) {
//保持心跳函数 30s发送一次
this.keep_alive_timer = setInterval(() => {
this.keepAlive();
}, 30000);
}
}
};
this.onmessage = e => {
try {
callback(JSON.parse(e.data));
} catch (error) {
callback(e.data, error);
}
};
this.onerror = e => {
this.reConnect();
};
this.onclose = e => {
let flag = sessionStorage.getItem('is_reconnect') || false
if (flag || this.is_destroy || (new Date().getTime() - this.reconnect_time >= 20000 && this.reconnect_count >= 10)) { //强制关闭连接
clearInterval(this.keep_alive_timer);
this.socket = null
} else {
this.reConnect();
}
};
};
/**
* 初始化websocket连接
* @param url
*/
WS.prototype.initWs = function () {
window.WebSocket = window.WebSocket || window.MozWebSocket;
if (!window.WebSocket) { // 检测浏览器支持
console.error('错误: 浏览器不支持websocket');
return;
}
this.last_health_time = -1; // 最近发送心跳的时间
this.is_reconnect = false;
this.is_destroy = false //强制关闭
if (this.protocol) {
this.socket = new WebSocket(this.url, this.protocol);
} else {
this.socket = new WebSocket(this.url);
}
this.socket.onopen = e => {
this.onopen(e);
};
this.socket.onmessage = e => {
this.onmessage(e);
};
this.socket.onclose = e => {
this.onclose(e);
};
this.socket.onerror = e => {
this.onerror(e);
};
return this;
};
/**
* 保持心跳函数
*/
WS.prototype.keepAlive = function () {
const socket = this.socket;
const time = new Date().getTime();
// 不是刚开始连接并且连接了50s(如果断网了,ws.send会无法发送消息出去)
if (this.last_health_time !== -1 && time - this.last_health_time > 50000) {
this.socket.close();
} else {
/*
【readyState:
CONNECTING:值为0,表示正在连接。
OPEN:值为1,表示连接成功,可以通信了。
CLOSING:值为2,表示连接正在关闭。
CLOSED:值为3,表示连接已经关闭,或者打开连接失败。】
ws.bufferedAmount === 0 发送完毕
*/
if (socket.bufferedAmount === 0 && socket.readyState === 1) {
if (this.json != '') {
let heartBeat = ''
if (typeof (this.json) == 'string') {
heartBeat = this.json
} else if (typeof (this.json) == 'object') {
try {
heartBeat = JSON.stringify(this.json)
} catch (e) {
e
}
}
socket.send(heartBeat)
}
this.last_health_time = time;
}
}
};
/**
* 断网重连
*/
WS.prototype.reConnect = function () {
clearInterval(this.keep_alive_timer);
if (!this.is_reconnect) {
this.is_reconnect = true;
this.reconnect_time = new Date().getTime();
this.reconnect_count++;
// 如果没有重连
this.reconnect_timer && clearTimeout(this.reconnect_timer);
this.reconnect_timer = setTimeout(() => { this.initWs() }, 2000);
}
};
/**
* 强制关闭
*/
WS.prototype.destroy = function () {
clearInterval(this.keep_alive_timer);
this.is_destroy = true;
if(this.socket){
this.socket.close()
}
};
export default WS;
调用
/**(e) => {} 回调函数,
JSON.stringify(obj): 初始化成功就发送,可发送心跳
socketUrl: url地址
str: 子协议
**/
let ws = new WS(JSON.stringify(obj), socketUrl, (e) => {
ws.socket.send() 发送消息
},str)
// 关闭连接
ws.destroy()
ithqva06721MS-企业建站!收录请看过来!http://www.jithendriyasujith.com//
123123123