封装websocket并在vuejs中调用
1、创建JS文件ce-websocket-util.js
class CeWebsocketUtil {
websocket = null;
reConnectTimes = 0; // 失败后重新连接次数
wsInterVal = null; // 重新连接定时器
maxReConnectTimes = 10; // 最大连接次数,默认10次
reIntervalTime = 60 * 1000; // 重连间隔时间,默认1min
currentComponent = null; // 当前调用的组件
/**
* 初始化Websocket数据
* @param {*} _this 当前this
* @param {*} url ws连接url
* @param {*} option,配置,传null时,默认 maxReConnectTimes = 10, reIntervalTime = 60000
*/
async initWebsocketData (_this, url, option) {
this.currentComponent = _this;
if (option && option.maxReConnectTimes) this.maxReConnectTimes = option.maxReConnectTimes;
if (option && option.reIntervalTime) this.reIntervalTime = option.reIntervalTime;
// 如果websocket不存在,则创建;存在的话,先关闭再创建
if (!this.websocket) return this.createWebsocket(url);
await this.closeWebsocket();
this.createWebsocket(url);
}
// 创建Websocket连接
createWebsocket (url) {
this.websocket = new WebSocket(url);
this.websocket.onopen = () => {
this.onOpen();
};
this.websocket.onmessage = e => {
this.onMessage(e);
};
this.websocket.onerror = () => {
this.onError();
};
this.websocket.onclose = () => {
this.onClose();
};
}
/*
* 连接成功
*/
onOpen () {
const NowFormatter = this.formatDateTime();
if (this.reConnectTimes > 0) {
console.info(`ws重连:第【${this.reConnectTimes}】次连接成功!****${this.websocket.url}****${NowFormatter}`);
} else {
console.info(`ws连接成功****${this.websocket.url}****${NowFormatter}`);
this.reConnectTimes = 0;
}
// 注册onWsOpen方法
this.currentComponent.onWsOpen();
}
/**
* 收到消息
* @param {*} e 消息事件
*/
onMessage (e) {
console.info(`ws收到消息****${this.websocket.url}****${e.data}`);
// 注册onWsMessage方法,接收消息
this.currentComponent.onWsMessage(e.data);
}
/**
* 连接失败
* @returns
*/
onError () {
const NowFormatter = this.formatDateTime();
console.error(`ws连接失败****${this.websocket.url}****${NowFormatter}`);
if (!this.wsInterVal) {
this.setWsInterval();
return;
}
// 超过最大连接次数后,不再连接
if (this.reConnectTimes >= this.maxReConnectTimes) {
console.error(`ws重连第【${this.reConnectTimes}】次失败,不再连接:****${this.websocket.url}****${NowFormatter}`);
this.clearWsInterval();
}
}
/**
* 设置定时器
*/
setWsInterval () {
console.info('设置定时器');
this.reConnect();
this.wsInterVal = setInterval(() => {
this.reConnect();
}, this.reIntervalTime);
}
/**
* 重新连接
*/
reConnect () {
// 先关掉 再连接
this.websocket && this.websocket.close();
const NowFormatter = this.formatDateTime();
this.reConnectTimes += 1;
console.info(`ws重连:正在尝试第【${this.reConnectTimes}】次连接:****${this.websocket.url}****${NowFormatter}`);
this.initWebsocket(this.currentComponent, this.websocket.url);
}
/**
* 清除定时器
*/
clearWsInterval () {
console.info('清除定时器');
clearInterval(this.wsInterVal);
this.wsInterVal = null;
}
/**
* 关闭连接
*/
closeWebsocket () {
console.info('关闭websocket');
this.websocket && this.websocket.close();
this.websocket = null;
this.reConnectTimes = 0;
this.clearWsInterval();
}
// 关闭连接
onClose () {
const NowFormatter = this.formatDateTime();
console.error(`ws断开连接****${NowFormatter}`);
}
/**
* 发送心跳
* @param {*} data
*/
sendHeartBeat (data) {
if (this.websocket) {
console.info(`sendHeartBeat${JSON.stringify(data)}`);
this.websocket.send(JSON.stringify(data));
}
}
/**
* 格式化new Date() YYYY-MM-DD HH:mm:ss:ms
* 控制台打印websocket信息时使用,
* @returns
*/
formatDateTime () {
const Now = new Date();
return `${Now.getFullYear()}-${Now.getMonth() + 1}-${Now.getDate()} ${Now.getHours()}:${Now.getMinutes()}:${Now.getSeconds()}:${Now.getMilliseconds()}`;
}
}
export default new CeWebsocketUtil();
2、VUE组件中
2.1 引入封装好的websocket
import CeWebsocketUtil from 'common/ce-websocket-util';
2.2、创建连接,初始化数据
CeWebsocketUtil.initWebsocketData(this, URL);
2.3、 websocket 连接成功
onWsOpen () {
console.log('websocket已连接成功');
},
2.4、发送心跳
CeWebsocketUtil.sendHeartBeat({ rule: "hello world" });
2.5、 接收websocket数据
onWsMessage (e) {
// TODO
}
2.6、主动关闭websocket
CeWebsocketUtil.closeWebsocket();