This commit is contained in:
zyy 2020-01-14 15:32:48 +08:00
commit e2e5cec0a3
4 changed files with 70 additions and 135 deletions

View File

@ -3,7 +3,7 @@ import { login, logout, getInfo } from '@/api/login';
import { getToken, setToken, removeToken } from '@/utils/auth';
import { getUserConfigInfo } from '@/api/management/user';
import { LoginParams } from '@/utils/login';
import { creatSubscribe, clearSubscribe, perpetualTopic, commonTopic } from '@/utils/stomp';
import { creatSubscribe, clearSubscribe, perpetualTopic, commonTopic, disconnect} from '@/utils/stomp';
import Cookies from 'js-cookie';
const user = {
@ -65,6 +65,9 @@ const user = {
SUBSCRIBE_UN: () => {
clearSubscribe(perpetualTopic);
clearSubscribe(commonTopic);
},
Disconnect: ()=>{
disconnect();
}
},
@ -188,6 +191,9 @@ const user = {
},
subscribe_un({commit}, params) {
commit('SUBSCRIBE_UN', params);
},
disconnect({commit}, params) {
commit('Disconnect', params);
}
}
};

View File

@ -43,6 +43,8 @@ service.interceptors.response.use(
EventBus.$emit('viewLoading', false);
// eslint-disable-next-line no-undef
EventBus.$emit('clearCheckLogin');
// 断开连接
store.dispatch('Disconnect');
MessageBox.confirm(i18n.t('tip.logoutTips'), i18n.t('tip.hint'), {
confirmButtonText: i18n.t('tip.confirmLogin'),
showCancelButton: false,

View File

@ -6,57 +6,38 @@ import store from '../store';
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
// var SockJS = require('sockjs-client');
// var Stomp = require('stompjs');
const isDev = process.env.NODE_ENV === 'development';
const isTest = process.env.NODE_ENV === 'test';
const websocketUrl = `${getBaseUrl()}/joylink-websocket?token=`;
// const websocketUrl = `http://192.168.3.6:9000/joylink-websocket?token=`;
const reconnectInterval = [0, 0, 3000, 5000, 10000, 30000, 60000];
var StompClient = function (headers) {
this.url = websocketUrl + getToken();
this.headers = headers || {};
this.subscribeMap = new Map(); // 已订阅,对象{dest:'', handler:function, sub: Object}
this.connect();
};
StompClient.prototype = {
socket: null,
clientIns: null,
subscribeMap: null,
url: '',
status: false,
sockStatus: 0,
headers: {
// 'X-Token': getToken()
},
count: 0,
topic: '',
onmessage: null,
checkTimer: null,
// 连接服务端
connect() {
return new Promise((resolve, reject) => {
try {
// 断开已有连接
if (this.clientIns && this.clientIns.connected) {
this.clientIns.disconnect();
this.clientIns = null;
}
// 建立连接对象(还未发起连接)
this.socket = new SockJS(websocketUrl + getToken());
// null, {transports:['websocket']}解决连接关闭后xhr_streaming无限循环
this.socket = new SockJS(websocketUrl + getToken(), null, {transports:['websocket', 'MozWebSocket']});
// 获取 STOMP 子协议的客户端对象
this.clientIns = Stomp.over(this.socket);
@ -64,19 +45,18 @@ StompClient.prototype = {
this.closeStompDebug();
// 向服务器发起websocket连接并发送CONNECT帧
const that = this;
this.clientIns.connect({ 'X-Token': getToken() }, () => {
console.info('连接成功.');
this.count = 0;
this.status = true;
that.count = 0;
that.status = true;
// 恢复订阅
if (this.topic && this.onmessage) {
this.unsubscribe(this.topic);
this.subscribe(this.topic, this.onmessage, this.headers);
}
that.subscribeMap.forEach((subscribe) => {
that.subscribe(subscribe.dest, subscribe.handler);
});
// 检测sock是否断开
if (!this.clientIns.ws.onclose) {
// sock断开回调
this.clientIns.ws.onclose = () => {
checkLoginLine().then(() => {
this.status = false;
@ -86,46 +66,12 @@ StompClient.prototype = {
this.logOut(err);
});
};
}
// 定时器检测网络
if (!this.checkTimer) {
this.checkTimer = setInterval(() => {
if (!this.status || !this.clientIns.ws.onclose) {
// 发送检测心跳如果失败则在如下情况时需要断开WebSocket;
// 40003/40004/40005: 登录过期;
// 50008: 非法的token;
// 50012: 其他客户端登录了;
// 50014: Token 过期了;
checkLoginLine().then(() => {
// 会有连接延时,需要多次判断
// 如果socket或着clientIns断开则重新连接
if (!this.status || !this.clientIns.ws.onclose) {
this.count++;
this.reconnect(this.count);
}
}).catch((err) => {
this.logOut(err);
});
}
}, 30000);
}
resolve(this);
}, () => {
if (this.checkTimer) {
clearInterval(this.checkTimer);
this.checkTimer = null;
}
checkLoginLine().then(() => {
this.connect();
}).catch((err) => {
if (err.code == 40003 || err.code == 40004 || err.code == 40005 || err.code == 50012) {
this.logOut();
}
if (err.code == 50008 || err.code == 50014) {
this.url = websocketUrl + getToken();
this.connect();
}
this.logOut(err);
});
});
} catch (err) {
@ -135,7 +81,7 @@ StompClient.prototype = {
},
logOut(err) {
if (err.code == 40003 || err.code == 40004 || err.code == 40005 || err.code == 50012) {
console.info(err);
MessageBox.confirm('你已被登出,请重新登录', '确定登出', {
confirmButtonText: '重新登录',
showCancelButton: false,
@ -145,26 +91,23 @@ StompClient.prototype = {
location.reload();// 为了重新实例化vue-router对象 避免bug
});
});
}
if (err.code == 50008 || err.code == 50014) {
this.url = websocketUrl + getToken();
this.status = false;
this.count++;
this.reconnect(this.count);
}
},
// 恢复链接
reconnect(count) {
console.info(`尝试第${count || 1}次连接.`);
this.connect().then(() => { }).catch(() => {
this.count++;
this.reconnect(this.count);
const that = this;
setTimeout(() => {
that.connect().then(() => { }).catch(() => {
that.count++;
that.reconnect(that.count);
});
}, reconnectInterval[that.count] || reconnectInterval[reconnectInterval.length - 1] );
},
closeStompDebug() {
if (this.clientIns) {
this.clientIns.debug = undefined;
if (isDev || isTest) {
this.clientIns.debug = function (message) {
console.debug(message);
@ -175,41 +118,26 @@ StompClient.prototype = {
// 订阅指定的topic
subscribe(topic, onmessage, headers) {
// const timeDelay = [1000, 2000, 5000, 10000];
this.topic = topic;
this.onmessage = onmessage;
this.headers = headers;
if (this.status) {
if (!this.subscribeMap) {
this.subscribeMap = new Map();
}
try {
var subscription = this.subscribeMap.get(topic);
if (!subscription) {
subscription = this.clientIns.subscribe(topic, onmessage, headers); // 接收消息通过 subscribe() 方法实现
this.subscribeMap.set(topic, subscription);
}
} catch (err) {
setTimeout(() => {
this.subscribe(topic, onmessage, headers);
}, 300);
}
if (!this.status) {
this.subscribeMap.set(topic, {dest: topic, handler: onmessage, sub: null});
} else {
setTimeout(() => {
this.subscribe(topic, onmessage, headers);
}, 300);
const sub = this.clientIns.subscribe(topic, onmessage);
this.subscribeMap.set(topic, {dest: topic, handler: onmessage, sub: sub});
}
},
unsubscribe(topic) {
if (this.subscribeMap) {
const subscription = this.subscribeMap.get(topic);
if (subscription) {
subscription.unsubscribe();
if (subscription && subscription.sub) {
subscription.sub.unsubscribe();
this.subscribeMap.delete(topic);
console.log('取消订阅');
}
} else if (subscription) {
this.subscribeMap.delete(topic);
}
},
@ -218,12 +146,9 @@ StompClient.prototype = {
if (this.status) {
if (msg) {
msg = JSON.stringify(msg);
}
try {
this.clientIns.send(url, {}, msg);
} catch (err) {
this.status = false;
this.send(url, msg);
} else {
console.error('发送消息为空');
}
} else {
setTimeout(() => {
@ -233,17 +158,12 @@ StompClient.prototype = {
},
disconnect() {
if (this.checkTimer) {
clearInterval(this.checkTimer);
this.checkTimer = null;
}
if (this.clientIns && this.clientIns.connected) {
this.clientIns.disconnect();
this.clientIns = null;
}
this.status = false;
console.log('断开连接');
console.info('断开连接');
}
};

View File

@ -35,3 +35,10 @@ export function clearSubscribe(topic) {
Vue.prototype.$stomp.unsubscribe(topic);
}
}
// 断开连接
export function disconnect() {
if (Vue.prototype.$stomp) {
Vue.prototype.$stomp.disconnect();
}
}