因项目需要,提前学了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})
|