import Vue from 'vue' import Cookies from 'js-cookie' import storeOnlineuser from "@/store/modules/onlineUser.js" import bus from "@/api/bus.js" import {dateFormatter} from "@/utils/validate" let socket = null; let lockReconnet = false; //避免重複連接 const TokenKey = 'USERTOKEN' const wsUrl = `${window.g.WEBSOCKETPATH}?token=${Cookies.get(TokenKey)}` ; console.log(wsUrl) let isReconnet = false; let globalCallback = null, sendData = null; //把要發送給socket的數據和處理socket返回數據的回調保存起來 //export用以登錄後調用 避免在登錄頁面也調用 export let createSocket = url => { //創建socket //判斷有無token if(!Cookies.get(TokenKey)){ return false } try { if ('WebSocket' in window) { socket = new WebSocket(url) } else if ('MozWebSocket' in window) { socket = new MozWebSocket(url) } Vue.prototype.socket = socket //需要主動關閉的話就可以直接調用this.socket.close()進行關閉,不需要的話這個可以去掉 initSocket() } catch (e) { reconnet(url) } } let sendMsg = (data, callback) => { //發送數據,接收數據 if (socket.readyState === 1) { globalCallback = callback; sendData = data; data = JSON.stringify(data); console.log('發送數據',data) socket.send(data); }else { setTimeout(() => { console.log(socket, '等待socket鏈接成功') sendMsg(data, callback) }, 3500) return false } socket.onmessage = ev => { callback && callback(ev) } } let initSocket = () => { //初始化websocket socket.onopen = () => { //heartCheck.reset().start() //暫時不需要做心跳檢測 if (isReconnet) {//執行全局回調函數 console.log('websocket重新連接了') isReconnet = false } console.log('websocket連接成功') } socket.onmessage = (ev) => { console.log(ev, '連接正常') //存數據 得考慮會不會被覆蓋的問題 let res = JSON.parse(ev.data) console.log('獲得消息',res) if(res.Type == 'Event' && res.Message.Data.type == '呼叫'){ //獲取到呼叫信息 發送信息 其他頁面獲取到以後 調用相應方法 根據業務需要寫 bus.$emit('refreshApplication'); bus.$notify.info({ title: res.Message.Data.type, dangerouslyUseHTMLString: true, message: `<strong>${res.Message.Data.sender}</strong>呼叫<strong>${res.Message.Data.receiver}</strong><br>呼叫時間:${dateFormatter(res.SendTime)}`, duration: 0, position: 'bottom-right' }); } //Type==Chat時Message內列表爲在線用戶數據列表 else if(res.Type == 'Chat'){ Vue.prototype.onlineUserRes = res.Message // 用來頁面遍歷顯示 也可以直接用store中的數據 storeOnlineuser.state.onlineUser = res.Message //存儲在線用戶信息 } //heartCheck.reset().start() //暫時不需要做心跳檢測 } socket.onerror = () => { console.log('websocket服務出錯了'); reconnet(wsUrl) } socket.onclose = () => { console.log('websocket服務關閉了'); reconnet(wsUrl)//防止自動斷開 } } let reconnet = url => { //重新連接websock函數 //判斷有無token if(!Cookies.get(TokenKey)){ return false } if (lockReconnet) return false isReconnet = true; lockReconnet = true setTimeout(() => { createSocket(url) lockReconnet = false }, 4000) } let heartCheck = { //心跳檢測 timeout: 60 * 1000, timeoutObj: null, serverTimeoutObj: null, reset() { clearTimeout(this.timeoutObj) clearTimeout(this.serverTimeoutObj) return this; }, start() { let that = this; this.timeoutObj = setTimeout(() => { //發送數據,如果onmessage能接收到數據,表示連接正常,然後在onmessage裏面執行reset方法清除定時器 socket.send('heart check') this.serverTimeoutObj = setTimeout(() => { socket.close() }, that.timeout) }, this.timeout) } } //避免刷新以後頁面沒有數據 createSocket(wsUrl) export default { sendMsg }
在main.js中應用
import socket from '@/utils/mysocket' Vue.prototype.sendMsg = socket.sendMsg
發送消息
export default { data() { return { callData: { Sender: this.$store.state.user.id,//發送者id Receiver: "",//接收者id SendTime: "",//2020-08-06T16:32:22.3224288+08:00 Message: { Event: "Call", Data: "",//發送的消息 }, Type: "Event" }, } } call(row){ let call = { sender : this.$store.state.user.userName, type:'呼叫', receiver: row.receiverName } //呼叫接受人 this.callData.Receiver = row.userId this.callData.Message.Data = call this.$message({ type: 'success', message: '已呼叫' }); this.getSocketData(this.callData) }, getSocketData(data){ this.sendMsg(data,ev=>{ console.log(JSON.parse(ev.data),'發送後回調獲取數據') }) }, }
接收消息
import bus from "@/api/bus.js" mounted(){ //獲取main.js的emit bus.$on('refreshApplication', () => { //按照業務需要調用方法 this.fetchData() }); },
項目退出
//關閉websocket Vue.prototype.socket.onclose()