1、建立webscoket.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;//重连次数
const url = new URL(location.href)
let type = url.searchParams.get('type') ? url.searchParams.get('type') : sessionStorage.getItem('type')
let userId = url.searchParams.get('userId') ? url.searchParams.get('userId') : sessionStorage.getItem('userId')
if (process.env.NODE_ENV == "development"){
var websocketUrl = `ws://10.8.0.66:8093/websocket/${userId}/${type}`;
}else{
var websocketUrl = `ws://36.112.128.108:8080/ws/${userId}/${type}`;
}
//心跳设置
var heartCheck = {
heart: {
type: '1',
content: 'heart',
sendId: userId
},//心跳包
timeout: 60 * 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连接成功");
//首次握手
if (type == '1'){
webSocketSend(heartCheck.heart);
}else{
}
isConnect = true;
heartCheck.start();
reConnectNum = 0;
}
//客户端接收服务端数据时触发,e为接受的数据对象
function webSocketOnMessage(e) {
console.log("websocket信息:", e);
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(e.data);//将data传给在外定义的接收数据的函数,至关重要。
}
//socket关闭时触发
function webSocketOnClose(e) {
heartCheck.clear();
isConnect = false; //断开后修改标识
console.log(e)
console.log('webSocket已经关闭 (code:' + e.code + ')')
//被动断开,重新连接
if (e.code == 1001 || 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,
webSocketSend
};
2、main函数中引入并挂载:
import webscoketApi from './utils/websoket'
Vue.prototype.$socketApi = webscoketApi
3、初始化webscoket:
this.$socketApi.initWebSocket(this.getsocketResult)
4、接收信息:
// socket信息返回接受函数
getsocketResult(data) {
this.$socketApi.getSock(this.getScoketMes)
},
getScoketMes(data){
if(sessionStorage.getItem('type') == '1'){
if (JSON.parse(data).type == '4') { //二号位反馈一号位
this.showWinTan = 1
this.showWinTanTitle = '任务完成'
} else if (JSON.parse(data).type == '5' && sessionStorage.getItem('userId') == '3') { //组长消息提示
this.$notify({
title: '消息通知',
duration: 0,
message: JSON.parse(data).content,
// position: 'bottom-right'
});
} else if (JSON.parse(data).type == '6') { //小程序反馈
this.$notify({
title: '消息通知',
duration: 0,
message: JSON.parse(data).content,
// position: 'bottom-right'
});
}
} else if (sessionStorage.getItem('type') == '2'){ //二号位
JSON.parse(data).type == '2' ? this.acceptFileShow = true : ''
if (JSON.parse(data).content != 'heart'){
sessionStorage.statusAllId = JSON.parse(data).id
this.statusAllId = JSON.parse(data).id
}
this.sendId = JSON.parse(data).sendId
this.toUserId = JSON.parse(data).toUserId
this.content = JSON.parse(data).content
if (JSON.parse(data).type == '7') { //催办 二号位接收
this.$notify({
title: '消息通知',
duration: 0,
message: JSON.parse(data).content,
// position: 'bottom-right'
});
}
}
},
5、发送消息:
this.$socketApi.sendSock({
type: '7',
sendId: sessionStorage.getItem('userId'),
content: '来自于一号位的关于' + val.task_name + '的催办',
toUserId: '2',
sendSystemTag: sessionStorage.getItem('type'),
toSystemTag: '2',
})