1、优化
参考了网上几篇文章,对其中代码做了优化,加了重连机制和心跳检测,添加相应注释。
我刚尝试的时候因为没有websocket服务端,无意中发现一个免费的服务端。一个帅哥服务端
如果你想自己玩玩WebSocket, 但是你又不想自己部署一个WebSocket服务器,你可以使用ws = new WebSocket('wss://echo.websocket.org/'), 你向echo.websocket.org发送消息,它会回复你同样的消息。
2、代码(在vue当中)
WebSocket到现在成功运行一个月,前端没出任何问题(2019-04-04更新)
data(){
return{
websock: null,
reconnectData:null,
lockReconnect:false, //避免重复连接,因为onerror之后会立即触发 onclose
timeout:10000, //10s一次心跳检测
timeoutObj:null,
serverTimeoutObj:null,
}
},
created(){
this.initWebSocket();
},
methods:{
initWebSocket(){
console.log('启动中')
let wsurl = '你的websockt url';
this.websock = new WebSocket(wsurl);
this.websock.onopen = this.websocketonopen; //连接成功
this.websock.onmessage = this.websocketonmessage; //广播成功
this.websock.onerror = this.websocketonerror; //连接断开,失败
this.websock.onclose = this.websocketclose; //连接关闭
}, //初始化weosocket
websocketonopen(){
console.log('连接成功')
this.heatBeat();
}, //连接成功
websocketonerror(){
console.log('连接失败')
this.reconnect();
}, //连接失败
websocketclose(){
console.log('断开连接');
this.reconnect();
}, //各种问题导致的 连接关闭
websocketonmessage(data){
this.heatBeat(); //收到消息会刷新心跳检测,如果一直收到消息,就推迟心跳发送
let msgData = JSON.parse(data);
}, //数据接收
websocketsend(data){
this.websock.send(JSON.stringify(data));
}, //数据发送
reconnect(){
if(this.lockReconnect){ //这里很关键,因为连接失败之后之后会相继触发 连接关闭,不然会连接上两个 WebSocket
return
}
this.lockReconnect = true;
this.reconnectData && clearTimeout(this.reconnectData);
this.reconnectData = setTimeout(()=>{
this.initWebSocket();
this.lockReconnect = false;
},5000)
}, //socket重连
heatBeat(){
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(()=>{
this.websocketsend({type:'心跳检测'}) //根据后台要求发送
this.serverTimeoutObj = setTimeout(()=> {
this.websock.close(); //如果 5秒之后我们没有收到 后台返回的心跳检测数据 断开socket,断开后会启动重连机制
}, 5000);
}, this.timeout)
}, //心跳检测
},
destroyed() {
this.lockReconnect = true;
this.websock.close() //离开路由之后断开websocket连接
clearTimeout(this.reconnectData); //离开清除 timeout
clearTimeout(this.timeoutObj); //离开清除 timeout
clearTimeout(this.serverTimeoutObj); //离开清除 timeout
}