vue项目使用Websocket留存

1.新建websocket.js文件

let Socket = ''
let setIntervalWesocketPush = null
let wsUrl = ''
let count = 0

/**
 * 建立websocket连接
 * @param {string} url ws地址
 */
export const createSocket = url => {
  Socket && Socket.close()
  wsUrl = url
  if (!Socket) {
    console.log('建立websocket连接')
    Socket = new WebSocket(url)
    Socket.onopen = onopenWS
    Socket.onmessage = onmessageWS
    Socket.onerror = onerrorWS
    Socket.onclose = oncloseWS
    window.onbeforeunload = closeWs
  } else {
    console.log('websocket已连接')
  }
}

/**打开WS之后发送心跳 */
const onopenWS = () => {
  sendPing();
}

export const closeWs = () => {
  Socket && Socket.close();
  Socket = null;
  console.log("已断开链接!")
}

/**连接失败重连 */
const onerrorWS = () => {
  Socket.close()
  clearInterval(setIntervalWesocketPush)
  count = count + 1;
  console.log('连接失败重连中')
  if (Socket.readyState !== 3 && count < 10) {
    Socket = null
    createSocket(wsUrl)
  } else {
    console.log("链接失败,请刷新页面重试");
  }
}

/**WS数据接收统一处理 */
const onmessageWS = e => {
  window.dispatchEvent(new CustomEvent('onmessageWS', {
    detail: {
      data: e.data
    }
  }))
}

/**
 * 发送数据但连接未建立时进行处理等待重发
 * @param {any} message 需要发送的数据
 */
const connecting = message => {
  setTimeout(() => {
    if (Socket.readyState === 0) {
      connecting(message)
    } else {
      Socket.send(JSON.stringify(message))
    }
  }, 1000)
}

/**
 * 发送数据
 * @param {any} message 需要发送的数据
 */
export const sendWSPush = message => {
  if (Socket !== null && Socket.readyState === 3) {
    Socket.close()
    createSocket(wsUrl)
  } else if (Socket.readyState === 1) {
    Socket.send(JSON.stringify(message))
  } else if (Socket.readyState === 0) {
    connecting(message)
  }
}

/**断开重连 */
const oncloseWS = () => {
  clearInterval(setIntervalWesocketPush)
  console.log('websocket已断开....正在尝试重连')
  if(Socket && Socket.readyState !== 2){
    Socket = null
    createSocket(wsUrl)
  }
}
/**发送心跳
 * @param {number} time 心跳间隔毫秒 默认5000
 * @param {string} ping 心跳名称 默认字符串ping
 */
export const sendPing = (time = 5000, ping = 'ping') => {
  clearInterval(setIntervalWesocketPush)
  Socket.send(ping)
  setIntervalWesocketPush = setInterval(() => {
    if(Socket){
      Socket.send(ping)
    }else{
      clearInterval(setIntervalWesocketPush)
    }
  }, time)
}

2.Websocket文件夹新建index.vue

<template>
  <div>
    <!-- <el-button class="test-style" @click="testSendMsg">test</el-button> -->
  </div>
</template>

<script>
import { createSocket, sendWSPush } from '@/config/websocket.js';
import { updateState } from '@/api/servers/gdep_config.js';
import msgRoute from '@/layout/mixin/msgRoute.js';
export default {
  name: 'websocket',
  mixins: [msgRoute],
  data() {
    return {
      userId: null,
      notifyInstance: null,
      timer: null
    };
  },
  created() {
    this.userId = JSON.parse(localStorage.getItem('cookie'))
      ? JSON.parse(localStorage.getItem('cookie')).userId
      : null;
    createSocket(
      `${window.location.protocol === 'https:' ? 'wss' : 'ws'}:${window.location.host}${
        process.env.VUE_APP_BASE_API
      }/message/websocket` //连接路径
    );
  },
  mounted() {
    window.addEventListener('onmessageWS', this.getsocketData);
  },
  destroyed() {
    window.removeEventListener('onmessageWS', this.getsocketData);
  },
  methods: {
    getsocketData(e) {
      let data = e && e.detail.data;
      let dataArr = [];
      let dataObj = {};
      console.log(data);
      if (data != 'ping' && data != '已有相同新连接,当前连接已下线') {
        data = data.replace(/\"id\":(\d+)/, '"id": "$1"');
        dataObj = JSON.parse(data);
        dataArr = dataObj.receiveId;
      } else {
        dataArr = data.split(',');
      }
      if (dataArr.includes(this.userId)) {
        this.notify(dataObj);
        if (this.timer) {
          return;
        } else {
          this.timer = setTimeout(() => {
            this.upDateNotice();
            this.timer = null;
          }, 8000);
        }
      }
    },
    notify(dataObj) {
      if (this.notifyInstance) {
        this.notifyInstance.close();
        this.sendNotify(dataObj);
      } else {
        this.sendNotify(dataObj);
      }
    },
    sendNotify(dataObj) {
      const h = this.$createElement;
      let _this = this;
      this.notifyInstance = this.$notify({
        title: `${dataObj.title}`,
        message: h(
          'div',
          {
            class: `${dataObj.messageType !== 2 ? `msg-box` : ``}`
          },
          `${dataObj.content}`
        ),
        type: dataObj.messageType === 2 ? 'warning' : 'info',
        position: 'bottom-right',
        duration: 0,
        onClick() {
          if (dataObj.messageType !== 2) {
            _this.toUpdate(dataObj);
            _this.notifyInstance.close();
          }
        }
      });
    },
    // 更改消息状态
    toUpdate(item) {
      let id = item.id.toString();
      let params = {
        id: id
      };
      updateState(params).then((res) => {
        if (res.code == 200) {
          this.upDateNotice();
        }
      });
      this.msgRouteGo(item);
    },
    upDateNotice() {
      this.$EventBus.$emit('upDateNotice', true);
    },
    testSendMsg() {
      let obj = {
        title: '测试数据标题',
        content: '测试数据',
        receiveId: '14200000000000009354',
        senderName: '公司名称',
        sender: 'brand',
        businessType: 'code',
        messageType: 1
      };
      sendWSPush(obj);
    }
  }
};
</script>
<style lang="scss" scoped>
.test-style {
  position: absolute;
  bottom: 0px;
  right: 0;
  z-index: 999999;
}
.msg-box {
  cursor: pointer;
  color: #0663ff;
  text-decoration: underline;
}
</style>

3.使用页面

<template>
  <div>
     <Websocket></Websocket>
  </div>
</template>
import { Websocket } from './components';//引用组件
export default {
  components: {
    Websocket
  },
}

4.说是不规范,因为什么不规范呢?字数太短?那我凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑凑一凑

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值