赞
踩
mounted() {
//确定本地是否存入用户id (如果有,代表用户已登入系统)
let userInfo = JSON.parse(localStorage.getItem("userInfo"));
this.id = userInfo.id;
if (this.id) {
this.initSocket();
}
},
ps: 确定本地是否存入用户id (如果有,代表用户已登入系统)
// 2.确定用户浏览器是否支持WebSocket initSocket() { if ("WebSocket" in window) { // let tcp = location.protocol === 'https:' ? 'wss:' : 'ws:'; // 2-1.如果已有ws开启,先关闭一次 进行我们自己的配置 this.ws && this.ws.close(); // 2-2.生产环境和非生产环境的协议配置 主要变量为 project 和 uid if(process.env.VUE_APP_TITLE === "stage"){ this.wsUrl = `ws://test.ws.chiefgr.com/?project=jd-shop&uid=` + this.id; }else{ this.wsUrl = 'ws://ws.chiefgr.com/?project=jd-shop&uid=' + this.id; } // 2-3. 配置一个我们对应的ws new WebSocket(this.wsUrl); this.initWebSocket(); } else { this.$notify({ message: "当前浏览器不支持消息通知,请升级或更换浏览器!", position: "bottom-right", duration: 5000 }); } },
ps: 判断用户浏览器是否支持ws,若支持,则进行我们需要的相关配置。
// ws事件方法
initWebSocket() {
this.ws = new WebSocket(this.wsUrl);
this.ws.onopen = this.wsOpen; //连接建立时触发
this.ws.onmessage = this.wsMessage; //客户端接收服务端数据时触发
this.ws.onerror = this.wsError; //通信发生错误时触发
this.ws.onclose = this.wsClose; //连接关闭时触发
},
先把完整代码贴上来 后面有时间再整理步骤解析,代码里的解析其实已经挺详细了
import { exportDownload } from "@/api/user"; export default { data() { return { wsUrl: "", id: "", token: "", ws: "", //建立的连接 lockReconnect: false, //是否真正建立连接 timeout: 45 * 1000, //30秒一次心跳 timeoutObj: null, //心跳心跳倒计时 serverTimeoutObj: null, //心跳倒计时 timeoutnum: null, //断开 重连倒计时 notificationStatus: false, // 系统通知 } }, created() { this.notifyMeAuth(); }, mounted() { // 1. 确定本地是否存入用户id let userInfo = JSON.parse(localStorage.getItem("userInfo")); this.id = userInfo.id; if (this.id) { // 1-1. 如果存在,代表用户已登入系统 开启连接websocket(下面简称ws) this.initSocket(); } }, beforeDestroy() { this.id = ""; this.timeoutnum && clearTimeout(this.timeoutnum); this.timeoutObj && clearTimeout(this.timeoutObj); this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj); this.ws && this.ws.close(); }, methods: { // 2.确定用户浏览器是否支持WebSocket initSocket() { if ("WebSocket" in window) { // let tcp = location.protocol === 'https:' ? 'wss:' : 'ws:'; // 2-1.如果已有ws开启,先关闭一次 进行我们自己的配置 this.ws && this.ws.close(); // 2-2.生产环境和非生产环境的协议配置 主要变量为 project 和 uid if(process.env.VUE_APP_TITLE === "stage"){ this.wsUrl = `ws://test.ws.chiefgr.com/?project=jd-shop&uid=` + this.id; }else{ this.wsUrl = 'ws://ws.chiefgr.com/?project=jd-shop&uid=' + this.id; } // 2-3. 配置一个我们对应的ws new WebSocket(this.wsUrl); this.initWebSocket(); } else { this.$notify({ message: "当前浏览器不支持消息通知,请升级或更换浏览器!", position: "bottom-right", duration: 5000 }); } }, // ws事件方法 initWebSocket() { this.ws = new WebSocket(this.wsUrl); this.ws.onopen = this.wsOpen; //连接建立时触发 this.ws.onmessage = this.wsMessage; //客户端接收服务端数据时触发 this.ws.onerror = this.wsError; //通信发生错误时触发 this.ws.onclose = this.wsClose; //连接关闭时触发 }, //重置心跳 reset() { //清除时间 clearTimeout(this.timeoutObj); clearTimeout(this.serverTimeoutObj); //重启心跳 this.start(); }, // 3.连接成功,发一个心跳给服务器 表示我们已准备好 wsOpen() { console.log("连接 成功", new Date()); // this.wsSend(); // 开启心跳 this.start(); }, //开启心跳 start() { var that = this; that.timeoutObj && clearTimeout(that.timeoutObj); that.serverTimeoutObj && clearTimeout(that.serverTimeoutObj); that.timeoutObj = setTimeout(function() { //3-1.这里发送一个心跳,后端收到后,返回一个心跳消息, if (that.ws.readyState == 1) { //readyState == 1 :连接已建立,可以通信 //如果连接正常 后端返回了信息,进入 6.数据接收 that.ws.send("heartCheck"); } else { //否则重连 //readyState == 0 :连接尚未建立; 2:连接正在关闭; 3:连接已经关闭或不能打开 that.reconnect(); } // 3-2.发送心跳超时,则关闭ws that.serverTimeoutObj = setTimeout(function() { //超时关闭 如果用户处于登录状态,则重连ws that.ws.close(); }, that.timeout); }, that.timeout); }, // 6.数据接收 wsMessage(res) { let data = JSON.parse(res.data); let dom = ""; // 根据返回的数据 判定是下载 还是消息通知 或者其他 (自行约定) if (data.title) { this.$store.dispatch("informLog/setNew", true); if (data.type == "App\\Notifications\\ExportReady") { // 6-1.下载 调下载接口exportDownload dom = `<div>${data.filename}</div>`; let newData = { filename: data.filename }; exportDownload(newData) .then(res => { let name = data.filename; let url = window.URL.createObjectURL(res.data); let link = document.createElement("a"); link.style.display = "none"; link.href = url; link.setAttribute("download", name); document.body.appendChild(link); link.click(); }) .catch(() => { this.$notify.error("下载错误"); }); } else { // 6-2.其他通知 dom = data.content; let text = ""; if (data.content) { text = data.content.replace(/<.*?>/g, ""); } // 发送桌面通知 this.notifyMe({ title: data.title, msg: text }); } // 7.接收到数据之后 (不管是哪种类型,在系统中调起弹窗发送通知) this.$notify({ title: data.title, dangerouslyUseHTMLString: true, message: dom, position: "bottom-right", duration: 15000 }); } // 8.收到服务器信息,心跳重置 {"code":2,"api_version":"1.12.4"} if (data.code == 2) { this.reset(); } }, // 发送消息 wsSend() { this.ws.send( JSON.stringify({ id: window.btoa(this.id) }) ); }, // 4.关闭 wsClose() { console.log("连接 关闭", new Date()); //4-1. 用户处于登录状态,重连ws if (this.id) { this.reconnect(); } }, // 错误 wsError(err) { console.log("连接 错误", new Date()); //重连 this.reconnect(); }, // 5.重连ws reconnect() { //重新连接 var that = this; if (that.lockReconnect) { return; } that.lockReconnect = true; //没连接上会一直重连,设置延迟避免请求过多 that.timeoutnum && clearTimeout(that.timeoutnum); that.timeoutnum = setTimeout(function() { //新连接 that.initWebSocket(); that.lockReconnect = false; }, 5000); }, // 系统 获取通知授权 notifyMeAuth() { let that = this; // 先检查浏览器是否支持 if (!("Notification" in window)) { if(!this.ddEvn){ alert("此浏览器不支持桌面通知"); } } // 检查用户是否同意接受通知 else if (Notification.permission === "granted") { that.notificationStatus = true; } // 否则我们需要向用户获取权限 // else if (Notification.permission !== 'denied') else { Notification.requestPermission(function(permission) { // 如果用户同意,就可以向他们发送通知 if (permission === "granted") { that.notificationStatus = true; } }); } }, // 系统 通知 notifyMe(obj) { if (this.notificationStatus) { let { title, msg } = obj; new Notification(title, { body: msg }); } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。