1.utils里新建websoket.js
import Vue from 'vue'
import { Message } from 'element-ui'
let v = new Vue()
v.$message = Message;
var webSocket = null;
var isConnect = false; //连接状态
var globalCallback = function(e){ console.log(e) };//定义外部接收数据的回调函数
var reConnectNum = 0;//重连次数
let userId = sessionStorage.getItem("userId")
var websocketUrl = `ws://192.168.124.60:9098/websocket/${userId}`;
//心跳设置
var heartCheck = {
heart:"heart",//心跳包
timeout: 45 * 1000, //每段时间发送一次心跳包 这里设置为60s
heartbeat: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
start: function () {
this.heartbeat = setInterval(()=>{
if (isConnect){
webSocketSend(this.heart);
}else{
this.clear();
}
}, this.timeout);
},
reset: function () {
clearInterval(this.heartbeat);
this.start();
},
clear:function(){
clearInterval(this.heartbeat);
}
}
//初始化websocket
function initWebSocket(callback) {
//此callback为在其他地方调用时定义的接收socket数据的函数
if(callback){
if(typeof callback == 'function'){
globalCallback = callback
}else{
throw new Error("callback is not a function")
}
}
if ("WebSocket" in window) {
webSocket = new WebSocket(websocketUrl);//创建socket对象
} else {
Message({
message: '该浏览器不支持websocket!',
type: 'warning'
});
return
}
//打开
webSocket.onopen = function() {
webSocketOpen();
};
//收信
webSocket.onmessage = function(e) {
webSocketOnMessage(e);
};
//关闭
webSocket.onclose = function(e) {
webSocketOnClose(e);
};
//连接发生错误的回调方法
webSocket.onerror = function(e) {
webSocketonError(e);
};
}
//连接socket建立时触发
function webSocketOpen() {
console.log("WebSocket连接成功");
//首次握手
webSocketSend(heartCheck.heart);
isConnect = true;
heartCheck.start();
reConnectNum = 0;
}
//客户端接收服务端数据时触发,e为接受的数据对象
function webSocketOnMessage(e) {
console.log("websocket信息:");
console.log(e.data)
if(e.data == "stopUser") {
Message({
message: '你已被上级管理员停用即将跳转登录页',
type: 'warning'
});
setTimeout(() => {
window.location.href = vueConfig.jqUrl + "vue/web/login"
}, 3000);
}
const data = JSON.parse(e.data);//根据自己的需要对接收到的数据进行格式化
globalCallback(data);//将data传给在外定义的接收数据的函数,至关重要。
}
//socket关闭时触发
function webSocketOnClose(e){
heartCheck.clear();
isConnect = false; //断开后修改标识
console.log(e)
console.log('webSocket已经关闭 (code:' + e.code + ')')
//被动断开,重新连接
if(e.code == 1006){
if(reConnectNum < 3){
initWebSocket();
++reConnectNum;
}else{
v.$message({
message: 'websocket连接不上,请刷新页面或联系开发人员!',
type: 'warning'
});
}
}
}
//连接发生错误的回调方法
function webSocketonError(e){
heartCheck.clear();
isConnect = false; //断开后修改标识
console.log("WebSocket连接发生错误:");
console.log(e);
}
//发送数据
function webSocketSend(data) {
webSocket.send(JSON.stringify(data));//在这里根据自己的需要转换数据格式
}
//在其他需要socket地方主动关闭socket
function closeWebSocket(e) {
webSocket.close();
heartCheck.clear();
isConnect = false;
reConnectNum = 0;
}
//在其他需要socket地方接受数据
function getSock(callback) {
globalCallback = callback
}
//在其他需要socket地方调用的函数,用来发送数据及接受数据
function sendSock(agentData) {
//下面的判断主要是考虑到socket连接可能中断或者其他的因素,可以重新发送此条消息。
switch (webSocket.readyState) {
//CONNECTING:值为0,表示正在连接。
case webSocket.CONNECTING:
setTimeout(function() {
sendSock(agentData, callback);
}, 1000);
break;
//OPEN:值为1,表示连接成功,可以通信了。
case webSocket.OPEN:
webSocketSend(agentData);
break;
//CLOSING:值为2,表示连接正在关闭。
case webSocket.CLOSING:
setTimeout(function() {
sendSock(agentData, callback);
}, 1000);
break;
//CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
case webSocket.CLOSED:
// do something
break;
default:
// this never happens
break;
}
}
export default {
initWebSocket,
closeWebSocket,
sendSock,
getSock
};
2.main.js引入挂载原
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import axios from "./utils/api/index";
import utils from "./utils";
import socketApi from "./utils/websocket";
Vue.prototype.$socketApi = socketApi;//websocket挂在原型上
3.使用
beforeDestroy() {//销毁的生命周期
this.$socketApi.closeWebSocket();
},
mounted() {//挂载的生命周期
this.$socketApi.initWebSocket(this.getsocketResult);
},
methods: {
// socket信息返回接受函数
getsocketResult(data) {
console.log(data);
},
//发送socket信息
websocketSend(data) {
this.$socketApi.sendSock(data);
},
},
4.业务中的使用
export default {
data() {
return {
badgeValue: 0, // 消息总条数
// websocket消息推送
ws: null, // websocket实例
wsUrl: "", // websocket连结url
tt: null,
heartCheck: null,
timeoutObj: null,
serverTimeoutObj: null,
timer: null, // 定时器
lockReconnect: false,
};
},
methods: {
// 页面获取用户信息
initPage() {
const loginInfo = JSON.parse(localStorage.getItem("loginInfo"));
this.wsUrl = `wss://xxxxxxxxx/api/management/wsmsg/${loginInfo.userId}`;
window.clearTimeout(this.timeoutObj);
window.clearTimeout(this.serverTimeoutObj);
window.clearTimeout(this.tt);
this.createWebSocket();
},
// 创建websocket
createWebSocket() {
try {
this.ws = new WebSocket(this.wsUrl);
this.initWebScoketFun();
} catch (e) {
this.reconnect(this.wsUrl);
}
},
// websocket消息提醒
initWebScoketFun() {
const timeout = 30000;
this.timeoutObj = null;
this.serverTimeoutObj = null;
this.heartCheck = {
start: () => {
this.timeoutObj && window.clearTimeout(this.timeoutObj);
this.serverTimeoutObj &&
window.clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(() => {
// 这里发送一个心跳,后端收到后,返回一个心跳消息,
this.ws.send("1");
this.serverTimeoutObj = setTimeout(() => {
this.ws.close();
}, timeout);
}, timeout);
},
};
this.ws.onclose = () => {
console.log("链接关闭", this.wsUrl);
this.reconnect(this.wsUrl);
};
this.ws.onerror = () => {
console.log("链接失败", this.wsUrl);
this.reconnect(this.wsUrl);
};
this.ws.onopen = () => {
// 心跳检测重置
this.heartCheck.start();
};
this.ws.onmessage = (event) => {
console.log(event, "webScoket心跳链接");
if (
event.data != "1" &&
event.data != "链接成功" &&
event.data.indexOf("newAutoOpenOrder") == -1
) {
//获取后台的小铃铛的数量、及重新调取列表接口
const data = JSON.parse(event.data);
this.badgeValue = data.msgnum;
this.getMessageList();
}
// 拿到任何消息都说明当前连接是正常的
this.heartCheck.start();
};
},
// 重新链接websocket
reconnect(url) {
if (this.lockReconnect) {
return;
}
this.lockReconnect = true;
// 没连接上会一直重连,设置延迟避免请求过多
this.tt && window.clearTimeout(this.tt);
this.tt = setTimeout(() => {
this.createWebSocket(url);
this.lockReconnect = false;
}, 60000);
},
// 获取未读消息列表
async getMarkallread() {
const res = await markallread(this.loginInfo.userId);
if (res && res.code == 200) {
this.getMessageList();
}
},
// 退出登录 清空WebSocket
logout() {
this.ws.onclose = () => { };
this.ws.onerror = () => { };
this.ws.close();
window.clearTimeout(this.timeoutObj);
window.clearTimeout(this.serverTimeoutObj);
this.$router.push("/login");
},
},