vue項目中應用wbSocket

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()

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章