(精华)2020年7月19日 vue 实时通信websocket的封装

import webSocket from '../webSocket.js';
export default {
  isIosAndroid() {
    var u = navigator.userAgent;
    var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, //android终端
      isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
      isChrome = u.indexOf('Safari'); //浏览器端
    return {
      isAndroid,
      isiOS,
      isChrome
    }
  },
  websocktSend(paramsObj) {
    // this --> store
    //这个是用来向后端websocket发送信息,发送之前需要先判断是否还处理链接状态
    var userId = localStorage.getItem('userId');
    var sendMsg = () => {
      window.socketServer.send(JSON.stringify(paramsObj)); //给后端发送信息
    }
    if (window.socketServer.readyState == 1) {
      sendMsg();
    } else {
      // 这里的this是$store,传递进来的
      // 这个this你并不知道
      webSocket.call(this, wsconPath[sceneParam] + userId).then(() => {
        sendMsg();
      });
    }
  },
  // 时间显示的几分钟、几小时、当天、昨天、前天以及更早的具体时间
  // 2019-12-07 09:58:23
  // JS计算两个日期时间差,天 小时 分 秒格式
  showDiffTime: function (startDate) {
    if (!startDate) {
      return;
    }
    var startDate = startDate.replace(new RegExp(/-/gm), "/");
    var startDateB = new Date(startDate);

    var updateHour = startDateB.getHours(),
      updateMin = startDateB.getMinutes();

    updateHour = updateHour < 10 ? '0' + updateHour : updateHour;
    updateMin = updateMin < 10 ? '0' + updateMin : updateMin;
    var endDate = new Date(); //现在的时间
    var diff = endDate.getTime() - startDateB.getTime(); //时间差的毫秒数
    //计算出相差天数
    var days = Math.floor(diff / (24 * 3600 * 1000));
    // 1.当天,显示:HH:MM
    // 2.昨天,显示:昨天 HH:MM
    // 3.前天,显示:前天 HH:MM
    // 4.更早,显示:****年**月**日 HH:MM

    if (days > 0) {
      if (days == 1) {
        return "昨天 " + updateHour + ':' + updateMin;
      }
      if (days == 2) {
        return "前天 " + updateHour + ':' + updateMin;
      }
      if (days > 2) {
        return startDate.split(' ')[0] + ' ' + updateHour + ':' + updateMin;
      }
    }
    if (days == 0) {
      return updateHour + ':' + updateMin;
    }
  },
  //  像scroll,resize,keyup scroll等事件频繁触发会引发页面的抖动甚至卡顿
  debounce(fn, delay) {
    delay = delay || 200;
    var timer = null;

    return function () {
      var arg = arguments;
      clearTimeout(timer);
      timer = setTimeout(function () {
        fn.apply(this, arg);
      }, delay);
    }
  },
}

//心跳检测
var heartCheck = {
    timeout: 3000, //每隔三秒发送心跳
    // num: 3,  //3次心跳均未响应重连
    timeoutObj: null,
    reset: function(){//接收成功一次推送,就将心跳检测的倒计时重置为30秒
        clearTimeout(this.timeoutObj);//重置倒计时
        this.start();
    },
    start: function(){
        //启动心跳检测机制,设置倒计时30秒一次
        this.timeoutObj = setTimeout(function(){
           //这里发送一个心跳,后端收到后,返回一个心跳消息,
            //onmessage拿到返回的心跳就说明连接正常
            var userId = localStorage.getItem('userId');
            if(!userId){
                return;
            }
            window.socketServer.send(JSON.stringify({
                photographerObjectId:'',
                type:'6',
                leavingContent:'',
                photographerId:userId  //留言摄影师编号
            })); //给后端发送信息
        },this.timeout)
    }
    //onopen连接上,就开始start及时,如果在定时时间范围内,onmessage获取到了服务端消息,
    //就重置reset倒计时,距离上次从后端获取消息30秒后,执行心跳检测,看是不是断了。
}


/**建立连接 */
function createWSConnect(path){
    var _store = this;
    
    if (typeof WebSocket === "undefined") {
        alert("您的浏览器不支持socket");
    } else { 
        return new Promise((resolve,reject)=>{
            // 实例化socket
            var socket = new WebSocket(path);
            // 监听socket连接
            socket.onopen = function(){
                console.log("socket连接成功!!!");   
                window.socketServer = socket;
                resolve(socket);
                //要不要把socket存放在store呢,看自己

                //心跳检测启动
                heartCheck.start();

            };
            socket.onclose = function (e) {
                console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)
                console.log(e);
                reconnect(path);
              }

            // 监听socket错误信息
            socket.onerror = function(){
                socket.close();
                reject();
                console.log("连接错误");
                reconnect(path);
            };
              // 监听socket消息,后端给到前端的数据
            socket.onmessage = function(res){
                if(res.data==1){
                    //检测心跳
                    heartCheck.reset();
                    return;
                }   
                var data = res.data && JSON.parse(res.data); 
                // _store.dispatch('UpdateChatBadge',{count:data.count})
                updateMsgForType.call(_store,data);
                
            };
        })
     }
}

//重新建立链接
reconnect.lockReconnect = false;//避免重复连接
reconnect.timer = '';
function reconnect(url) {
    if (reconnect.lockReconnect) return;
    reconnect.lockReconnect = true;

    reconnect.timer && clearTimeout(reconnect.timer);
    //没连接上会一直重连,设置延迟避免请求过多
    reconnect.timer = setTimeout(function () {     
        createWSConnect(url);
        reconnect.lockReconnect = false;
    }, 4000);
}

function updateMsgForType(data){
    if(data.error){
        this.$Toast(data.error);
        return;             
    }

    this.dispatch('UpdateChatBadge',{count:data.count})
    switch(data.type){
        case '0':  // 0 一对一交流文字
            this.dispatch('communication/addOneToOne',data.siteComm)
        break;
        case '1': //1 一对一交流图片
            this.dispatch('communication/addOneToOne',data.siteComm)
        break;
        case '2': //2  未读总条数 
        break;
        case '3': //撤回被删除的信息
            this.dispatch('communication/withdrawOneToOne',{count:data.siteComm})

        break;
        case '4': //单条代表删除一对一信息
            this.dispatch('communication/delOneToOne',data.siteComm)
        break;
        case '5': //批量删除一对一信息
            this.dispatch('communication/delAllOneToOne',data.siteComm)
        break;
    }
}
export default createWSConnect;

utils.websocktSend.call(this.$store, paramsObj);

猜你喜欢

转载自blog.csdn.net/aa2528877987/article/details/107448747