赞
踩
在vue中用websocket实现实时通信,通过设置心跳时间来监测连接是否存在,若心跳时间内并没接收到任何消息,将自动重连。
心跳机制: 客户端每隔一段时间向服务端发送一个特有的心跳消息,每次服务端收到消息后只需将消息返回,此时,若二者还保持连接,则客户端就会收到消息,若没收到,则说明连接断开,此时,客户端就要主动重连,完成一个周期
断线重连: 若某时间段内客户端发送了消息,而服务端未返回,则认定为断线;这个时候会触发到websocket中的onclose事件,需要重新连接服务
<script> export default { data() { return { // websocket相关 scoket: null, // websocket实例对象 //心跳检测 heartCheck: { vueThis: this, // vue实例 timeout: 30000, // 超时时间(心跳时间),超过30s无消息推送,重新发送连接 timeoutObj: null, // 计时器对象——向后端发送心跳检测 serverTimeoutObj: null, // 计时器对象——等待后端心跳检测的回复 // 心跳检测重置 reset: function () { clearTimeout(this.timeoutObj); clearTimeout(this.serverTimeoutObj); return this; }, // 心跳检测启动 start: function () { this.timeoutObj && clearTimeout(this.timeoutObj); this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj); this.timeoutObj = setTimeout(() => { // 这里向后端发送一个心跳检测,后端收到后,会返回一个心跳回复 this.vueThis.scoket.send("HeartBeat"); console.log("发送心跳检测"); this.serverTimeoutObj = setTimeout(() => { // 如果超过一定时间还没重置计时器,说明websocket与后端断开了 console.log("未收到心跳检测回复"); // 关闭WebSocket this.vueThis.scoket.close(); }, this.timeout); }, this.timeout); }, }, socketReconnectTimer: null, // 计时器对象——重连 socketReconnectLock: false, // WebSocket重连的锁 socketLeaveFlag: false, // 离开标记(解决 退出登录再登录 时出现的 多次相同推送 问题,出现的本质是多次建立了WebSocket连接) } }, mounted() { this.createWebSocket(); }, methods: { // websocket启动 createWebSocket() { let webSocketLink = `ws://xxx`; // webSocket地址 try { let { WebSocket, MozWebSocket } = window; if ("WebSocket" in window) { // 谷歌 this.scoket = new WebSocket(webSocketLink); } else if ("MozWebSocket" in window) { // 火狐 this.scoket = new MozWebSocket(webSocketLink); } else { alert("您的浏览器不支持 WebSocket!"); } // websocket事件绑定 this.socketEventBind(); } catch (e) { // websocket重连 this.socketReconnect(); } }, // websocket事件绑定 socketEventBind() { // 连接成功建立的回调 this.scoket.onopen = this.onopenCallback; // 连接发生错误的回调 this.scoket.onerror = this.onerrorCallback; // 连接关闭的回调 this.scoket.onclose = this.oncloseCallback; // 向后端发送数据的回调 this.scoket.onsend = this.onsendCallback; // 接收到消息的回调 this.scoket.onmessage = this.getMessageCallback; //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = () => { this.scoket.close(); }; }, // websocket重连 socketReconnect() { if (this.socketReconnectLock) { return; } this.socketReconnectLock = true; this.socketReconnectTimer && clearTimeout(this.socketReconnectTimer); this.socketReconnectTimer = setTimeout(() => { console.log("WebSocket:重连中..."); this.socketReconnectLock = false; // websocket启动 this.createWebSocket(); }, 4000); }, // 连接成功建立的回调 onopenCallback() { console.log("WebSocket:已连接"); // 心跳检测重置 this.heartCheck.reset().start(); }, // 连接发生错误的回调 onerrorCallback() { console.log("WebSocket:发生错误"); // websocket重连 this.socketReconnect(); }, // 连接关闭的回调 oncloseCallback() { console.log("WebSocket:已关闭"); // 心跳检测重置 this.heartCheck.reset(); if (!this.socketLeaveFlag) { // 没有离开——重连 // websocket重连 this.socketReconnect(); } }, // 向后端发送数据的回调 onsendCallback() { console.log("WebSocket:发送信息给后端"); }, // 接收到消息的回调 getMessageCallback(rowInfo) { // 心跳回复——心跳检测重置 if (rowInfo.data.indexOf("HeartBeat") > -1) { // 收到心跳检测回复就说明连接正常 this.heartCheck.reset().start(); // 心跳检测重置 } else { // 普通推送——正常处理 console.log(rowInfo); // ======= 在此进行逻辑处理 ========= } } }, destroyed() { // 离开标记 this.socketLeaveFlag = true; // 关闭WebSocket this.scoket.close(); }, } </script>
兼容 谷歌 与 火狐
服务连接
服务端推送的消息
【1】廖雪峰:WebSocket
【2】阮一峰:WebSocket教程
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。