WebScoket入门(vue2)
WebScoket入门(vue2)
·
因项目需要,提前学了WebSocket,分享一些经验,也是做一个学习文档吧在这里。
1.介绍WebSocket
首先WebScoket它是一种网络传输协议。
http请求一般都是前端请求之后,后端推送数据给前端,否则无法拿到数据。WebSocket的出现就使得服务端可以主动推送消息给客户端,客户端也可以主动请求数据。网上很多聊天系统都用WebSocket来实现,我这边处理的需求是表格,实现上来说也都大同小异。
总的来说,WebSocket就是做实时响应的一种工具。
2.实现
直接讲实现吧,代码贴在这里。
class WebsocketConn {
constructor(url, cb) {
this.cb = cb;
this.url = url
this.ws = null;
this.s=0 //检测错误重新连接次数
this.isnor=true//标记字段,表明是否是正常的请求
this.lockReconnect = false; //避免ws重复连接
this.timeout = 30000; // 心跳检测时间
this.heartCheckTimer = null // 心跳检测定时器
this.heartCheckServerTimer = null;
this.timetag=null
}
heartCheckToReset() {
clearTimeout(this.heartCheckTimer);
clearTimeout(this.heartCheckServerTimer);
return this;
}
heartCheckToStart() {
this.heartCheckTimer && clearTimeout(this.heartCheckTimer);
this.heartCheckServerTimer && clearTimeout(this.heartCheckServerTimer);
this.heartCheckTimer = setTimeout(() => {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage 拿到返回的心跳就说明连接正常
this.ws.send("天王盖地虎");
console.log("天王盖地虎")
this.heartCheckServerTimer = setTimeout(() => {//如果超过一定时间还没重置,说明后端主动断开了
console.log("后端主动断开")
this.isnor=false
this.ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
}, this.timeout)
}, this.timeout)
}
create() {
// console.log(this.url)
try{
if('WebSocket' in window){
this.ws = new WebSocket(this.url);
//console.log(this.ws)
}
this.initEventHandle();
}catch(e){
this.reconnect(this.url);
console.log(e);
}
}
initEventHandle() {
// console.log(this.cb)
const _this=this
this.ws.onclose = (error) => {
!this.isnor && this.reconnect(this.url);
console.log("错误",error)
console.log("websocket 连接关闭!"+ new Date().toLocaleString());
};
this.ws.onerror = (error) => {
this.s++
if(this.s<6){//错误连接次数小于6,尝试重连
this.reconnect(this.url);
this.isnor=false;//标记字段,不是正常的请求,是重新连接
}else{//错误连接次数大于等于6
this.isnor=true;//重新开始正常请求
this.s=0;//错误次数重置为零
}
console.log("websocket 连接错误!"+this.s);
};
this.ws.onopen = () => {
this.heartCheckToReset().heartCheckToStart(); //心跳检测重置
this.s=0
// console.log("websocket 连接成功!"+new Date().toLocaleString());
};
this.ws.onmessage = (event) => { //如果获取到消息,心跳检测重置
this.s=0
// console.log('websocket订阅A'+event)
_this.cb(event)
if (event.data === '宝塔镇河妖') {
this.heartCheckToReset().heartCheckToStart();
return
}
// this.heartCheckToReset().heartCheckToStart(); //拿到任何消息都说明当前连接是正常的
// this.cb();
// console.log(event)
// console.log("websocket 收到消息啦:" + event);
};
}
reconnect() {
console.log("重新连接")
if(this.lockReconnect) return;
this.lockReconnect = true;
this.timetag && clearTimeout(this.timetag)
this.timetag=setTimeout(() => { //重连,设置延迟避免请求过多
this.create(this.url);
this.lockReconnect = false;
}, 2000);
}
close() {
this.ws.close();
}
}
export default WebsocketConn
代码比较全,后续有时间的话我会再上一版精简的,更通俗简单一些的。
3.注意
还有想说一点的是在学习的时候发现有的人将scoket.io 和ws、nodejs-websocket混为一谈。
scoket.io:是对 WebSocket的封装,
而ws和nodejs-websocket是WebSocket的库,如果是https那么对应的就是wss。
ps:如果要ws.send()一个对象记得转换成string类型,JSON.stringfy({XXX})
简单版:
data中先定义WS地址
JS代码如下:
mounted() {
setTimeout(() => {
this.initSysWebsocket(); //开启连接WS
});
},
methods: {
async initSysWebsocket() {
try {
if ("WebSocket" in window) {
console.log(this.wsUrl);
// 正式环境参数
this.websocket = new WebSocket(this.wsUrl); // 初始化
console.log(this.websocket);
this.initWebSocket();
}
} catch (e) {
console.log("尝试创建连接失败");
// 如果无法连接上webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接
this.reConnect();
}
},
reConnect() {
// 重连函数
var that = this;
if (this.isConnect) return;
this.rec && clearTimeout(this.rec);
// 延迟5秒重连 避免过多次过频繁请求重连
this.rec = setTimeout(function () {
that.createWebSocket();
}, 5000);
},
initWebSocket() {
this.isConnect = true;
// 连接错误
this.websocket.onerror = this.setErrorMessage;
// 连接成功
this.websocket.onopen = this.setOnopenMessage;
// 收到消息的回调
this.websocket.onmessage = this.setOnmessageMessage;
// 连接关闭的回调
this.websocket.onclose = this.setOncloseMessage;
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = this.onbeforeunload;
},
setErrorMessage() {
this.isConnect = false;
// 调用重连函数
this.reConnect();
console.log(
"WebSocket连接发生错误 状态码:" + this.websocket.readyState
);
},
setOnopenMessage() {
console.log("WebSocket连接成功 状态码:" + this.websocket.readyState);
if (this.queryId) {
// console.log(" WS this.queryId", this.queryId);
this.websocket.send(
JSON.stringify({
groupId: this.queryId,
identify: this.identifyItem,
name: this.nameItem,
objectAddress: this.objectAddressItem,
pageNum: this.$store.state.taosStore.pageNum,
pageSize: this.$store.state.taosStore.pageSize,
})
);
this.queryId = "";
} else {
this.websocket.send(
JSON.stringify({
groupId: this.nodeCheck,
identify: this.identifyItem,
name: this.nameItem,
objectAddress: this.objectAddressItem,
pageNum: this.$store.state.taosStore.pageNum,
pageSize: this.$store.state.taosStore.pageSize,
})
);
// 非页码变化清空选中节点id
if (!this.$store.state.taosStore.pageNum) {
this.nodeCheck = "";
}
}
},
setOnmessageMessage(event) {
// 根据服务器推送的消息做自己的业务处理
var json = JSON.parse(event.data);
// 获取标签数据
var markerData = json;
console.log("list数据", markerData);
this.getList = markerData;
},
setOncloseMessage() {
this.isConnect = false;
// 重连
this.reConnect();
// console.log('connection closed (' + e.code + ')')
console.log("WebSocket连接关闭 状态码:" + this.websocket.readyState);
},
onbeforeunload() {
this.closeWebSocket();
},
closeWebSocket() {
this.websocket.close();
},
原理也非常简单,就是this.setOnopenMessage连接成功后给后端传递相应的参数,this.setOnmessageMessage收到消息后调后赋值就可以了。
更多推荐
已为社区贡献3条内容
所有评论(0)