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

  

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