vue封装websocket_Vue 封装WebSocket+检测心跳+客服

1. 创建socket.js类import store from '@/store/index.js';

import API from '@/api/http.js';

// webScoket

let websock = {}; //建立的连接

let lockReconnect = false; //是否真正建立连接

let timeout = 60 * 1000; // 1分钟一次心跳

let timeoutObj = null; //心跳心跳倒计时

let serverTimeoutObj = null; //心跳倒计时

let timeoutnum = null; //断开 重连倒计时

// 一进入就加载

initWebSocket();

// 初始化weosocket

function initWebSocket() {

let user = localStorage.getItem('user');

if (user !== '' && user !== undefined) { // 在用户未登录的情况下不进行连接

// 建立连接

websock = new WebSocket ('你的webSocket地址');

// 连接成功

websock.onopen = websocketonopen;

// 连接错误

websock.onerror = websocketonerror;

// 连接关闭

websock.onclose = websocketclose;

// 接收信息

websock.onmessage = websocketonmessage;

} else {

//清除时间

clearTimeout(timeoutObj);

clearTimeout(serverTimeoutObj);

}

}

// 重新连接

function reconnect() {

if (lockReconnect) {

return;

}

lockReconnect = true;

// 没连接上会一直重连,设置延迟避免请求过多

timeoutnum && clearTimeout(timeoutnum);

timeoutnum = setTimeout(function() {

// 新连接

initWebSocket();

lockReconnect = false;

}, 5000);

}

//重置心跳

function reset() {

//清除时间

clearTimeout(timeoutObj);

clearTimeout(serverTimeoutObj);

//重启心跳

let user = localStorage.getItem('qrtMallUser');

if (!meetNull(user)) {

console.log('退出了登录,不需要重连');

return;

}

start();

}

//开启心跳

function start() {

timeoutObj && clearTimeout(timeoutObj);

serverTimeoutObj && clearTimeout(serverTimeoutObj);

timeoutObj = setTimeout(() => {

//这里发送一个心跳,后端收到后,返回一个心跳消息,

if (websock.readyState == 1) {

//如果连接正常

websock.send("heartCheck");

} else {

//否则重连

reconnect();

}

serverTimeoutObj = setTimeout(() => {

//超时关闭

websock.close();

}, timeout);

}, timeout);

}

//连接成功事件

function websocketonopen() {

//开启心跳

start();

}

//连接失败事件

function websocketonerror(e) {

//错误

//重连

lockReconnect = false;

reconnect();

}

//连接关闭事件

function websocketclose(e) {

//关闭

console.log("connection closed ");

//提示关闭

//重连

reconnect();

}

function websocketsend(msg) {

//向服务器发送信息

//数据发送

if (websock.readyState == 1) {

websock.send(msg);

} else {

websock.close();

initWebSocket();

}

}

// 接收服务器返回的数据

function websocketonmessage(e) {

let resData = JSON.parse(e.data);

// 获取当前在哪个路由,可以在路由文件存储如:router.beforeEach((to, from, next) => {essionStorage.setItem('url', to.fullPath);});

let toUrl = sessionStorage.getItem('url');

if (resData.type == "init") {

// 请求接口绑定用户到后端(API是我封装的axios请求)

let para = {client_id: resData.client_id };

API.post("service/bind", para, 1).then(res => {

if (res.status == 1) {

store.commit('changeSocketLocal', websock);

}

});

} else if (resData.type == "msg_add") {

if ( toUrl == '/chat') {

// 正在聊天界面

store.commit('changeServiceInfosLocal', resData); // 把消息保存到Vuex中

} else { // 不在聊天界面中

eventStorage(); // 用于消息声音提醒

// 设置未读条数

let onReadMsgNum = localStorage.getItem("noReadNum"); // 把原有未读的条数一起累加

++onReadMsgNum;

localStorage.setItem("noReadNum", onReadMsgNum);

store.commit('changeNoMsgReadNumLocal', onReadMsgNum); // 把未读的条数保存到Vuex中,解决有新消息页面未刷新不能及时更新的问题

}

}

// 收到服务器信息,心跳重置

reset();

}

function eventStorage () {

// 监听storage的变化, 用于消息声音提醒

var orignalSetItem = localStorage.setItem;

localStorage.setItem = function(key,newValue){

var setItemEvent = new Event("setItemEvent");

setItemEvent.newValue = newValue;

window.dispatchEvent(setItemEvent);

orignalSetItem.apply(this ,arguments);

}

}

export {

// 暴露出去,方便调用

initWebSocket

}

2.进入系统开启websocket, 在main.js引入import * as socket from '@/assets/js/socket.js'

Vue.prototype.$SOCKET = socket;

3.回显webSocket的数据

{{dataList}}

import { mapMutations, mapState } from 'vuex';

export default {

data() {

return {

webSocket: {readyState: 0},

dataList: []

};

},

created() {

localStorage.removeItem('noReadNum'); // 移除未读消息

document.body.removeEventListener('setItemEvent', function (event) {

event.preventDefault();  // 移除对storage的监听

},false);

this.changeNoMsgReadNumLocal(0); // 未读数清零

},

computed: {

...mapState(['serviceInfosLocal', 'socketLocal'])

},

watch: {

serviceInfosLocal  (newVal, oldval) { // 获取客服发送的消息

this._getHttpMsgInfo(newVal.data);

},

socketLocal (newVal) { // 保存的webSoket对象, 用于获取连接状态

this.webSocket = newVal;

},

},

methods: {

...mapMutations(['changeNoMsgReadNumLocal']),

_getHttpMsgInfo (resData) {    // 接收到服务器消息

let toUrl = sessionStorage.getItem('url');

if (toUrl.includes('chat')) {

// 在聊天界面,直接把消息push到数据里,用于界面回显

this.dataList.push(resData);

}

// 向服务器发送数据

if (this.webSocket !== undefined && this.webSocket.readyState == 1) {

this.webSocket.send(resData);

}

},

},

};

3.显示未读条数

{{readNum}}

import { mapState } from "vuex";

export default {

data() {

return {

readNum: "",

};

},

computed: {

...mapState(["noMsgReadNumLocal"])

},

created() {

let val = localStorage.getItem('noReadNum');

this.getNoReadMsg(val);

},

watch: {

noMsgReadNumLocal: { // 监听Vuex noMsgReadNumLocal数据的变化

handler: function(val, oldval) {

this.getNoReadMsg(val);

}

}

},

methods: {

getNoReadMsg(val) {

// 获取未读条数

if (val !== '') {

this.readNum = "";

} else {

if (Number(val) > 99) {

this.readNum = "99+";

} else {

this.readNum = val;

}

}

}

},

};

4.新消息声音提醒

在index.html写入:

// 客服新信息声音提醒

window.addEventListener("setItemEvent", function (e) {

if (localStorage.getItem('noReadNum')) {

var elem = document.getElementById('MsgaudioTs');

//播放

if (elem.paused) {

elem.play();

}

}

});

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值