在我们近年来的前端开发中其实很频繁的使用这种数据更新模式。
只是对于前端来讲,初级前端开发在不更新技术的情况,很多人还是使用轮巡的方法去定时调用接口刷新数据。
而webScoket就是为了解决轮巡所产生的多种弊端而产生的。
下面就是本人使用webScoket的vue项目代码方案,也参考了其他代码进行优化完善。
mounted() {
this.newWebSocket()
setTimeout(() => {
this.loading = false
}, 1000)
},
destroyed() {
this.websocket && this.websocket.close()
},
实现webSocket
newWebSocket() {
let _this = this
// let currentIp = this.$axios.defaults.baseURL.split('http://').join(''); //这里是取的vue项目中IP配置地址
// let currentIp = '192.168.1.251:8091'
var wsUrl = 'ws://' + currentIp + '/api/websocket/server';
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
this.websocket = new WebSocket(wsUrl);
} else {
this.$message.error('Not support websocket');
};
//连接发生错误的回调方法
this.websocket.onerror = function () {
console.log("出错");
_this.reconnect(wsUrl);
};
//连接成功建立的回调方法
this.websocket.onopen = function (event) {
heartCheck.reset().start(); //心跳检测重置
console.log("open");
};
//接收到消息的回调方法
this.websocket.onmessage = function (event) {
heartCheck.reset().start();
// 这里是获取到数据后我们的操作行为,对应方法也就不需要写了,对照后台返回的数据格式进行操作,注意:心跳检测的时候,后台会返回我们定义好的文字(这里为ping),在我们接数据的时候需要考虑将此数据过滤掉。
if (event.data && event.data !== 'onMessage->ping') {
this.warningNotify(jsonObj.data.data)
}
}
};
//连接关闭的回调方法
this.websocket.onclose = function () {
console.log("close");
};
//心跳检测
var heartCheck = {
timeout: 50000, //1分钟发一次心跳
timeoutObj: null,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
var self = this;
self.timeoutObj && clearTimeout(self.timeoutObj);
self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj);
self.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//readyState 拿到返回的心跳的状态readyState 1为正常
_this.websocket.readyState == 1 && _this.websocket.send("ping");
self.serverTimeoutObj = setTimeout(function () {//如果超过一定时间还没重置,说明后端主动断开了
_this.websocket.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
}, self.timeout)
}, this.timeout)
}
}
},
sendMsg() {
this.websocket && this.websocket.send('我的');
},
reconnect() {
let lockReconnect = false
if (lockReconnect) return;
lockReconnect = true;
setTimeout(() => { //没连接上会一直重连,设置延迟避免请求过多
this.newWebSocket();
lockReconnect = false;
}, 2000);
}
对比网上的一些webScoket我进行了一些优化,优化点如下。
1.webScoket连接错误onerror的时候执行reconnect方法重连,但是关闭onclose的时候不进行重连。因为连接错误并断开会进入对应两个方法,如果两个方法都进行重连,当切换路由时是会触发onclose,会出现页面已经跳转,但还会重连webScoket的问题。
2.在_this.websocket.readyState == 1 && _this.websocket.send("ping")里,我将原本网上的_this.websocket && _this.websocket.send("ping")进行修改,因为当服务器端断开时,websocket其实还没有销毁,会导致报错WebSocket is already in CLOSING or CLOSED state.,所以直接修改用连接状态readyState判断。
网友评论