2019-07-02 16:29:52 +08:00
|
|
|
|
import { handleToken } from '@/utils/auth';
|
|
|
|
|
import { checkLoginLine } from '@/api/login';
|
2019-08-12 11:01:00 +08:00
|
|
|
|
import { getBaseUrl } from '@/utils/baseUrl';
|
2019-09-03 10:45:58 +08:00
|
|
|
|
import { MessageBox } from 'element-ui';
|
|
|
|
|
import store from '../store';
|
|
|
|
|
import { gainClientId } from '@/utils/auth';
|
2019-07-02 16:29:52 +08:00
|
|
|
|
|
|
|
|
|
var SockJS = require('sockjs-client');
|
|
|
|
|
var Stomp = require('stompjs');
|
|
|
|
|
|
|
|
|
|
const isDev = process.env.NODE_ENV === 'development';
|
2019-07-26 17:13:03 +08:00
|
|
|
|
const websocketUrl = `${getBaseUrl()}/joylink-websocket?token=`;
|
2019-08-14 16:15:44 +08:00
|
|
|
|
// const websocketUrl = `http://192.168.3.6:9000/joylink-websocket?token=`;
|
2019-07-02 16:29:52 +08:00
|
|
|
|
|
|
|
|
|
var StompClient = function (headers) {
|
|
|
|
|
this.url = websocketUrl + handleToken();
|
|
|
|
|
this.headers = headers || {};
|
|
|
|
|
this.connect();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
StompClient.prototype = {
|
|
|
|
|
socket: null,
|
|
|
|
|
|
|
|
|
|
clientIns: null,
|
|
|
|
|
|
|
|
|
|
subscribeMap: null,
|
|
|
|
|
|
|
|
|
|
url: '',
|
|
|
|
|
|
|
|
|
|
status: false,
|
|
|
|
|
|
|
|
|
|
sockStatus: 0,
|
|
|
|
|
|
|
|
|
|
headers: {
|
2019-09-03 10:45:58 +08:00
|
|
|
|
// 'X-Token': handleToken()
|
2019-07-02 16:29:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
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 + handleToken());
|
|
|
|
|
|
|
|
|
|
// 获取 STOMP 子协议的客户端对象
|
|
|
|
|
this.clientIns = Stomp.over(this.socket);
|
|
|
|
|
|
|
|
|
|
this.closeStompDebug();
|
|
|
|
|
|
|
|
|
|
// 向服务器发起websocket连接并发送CONNECT帧
|
2019-08-12 11:01:00 +08:00
|
|
|
|
this.clientIns.connect({ 'X-Token': handleToken() }, () => {
|
2019-07-02 16:29:52 +08:00
|
|
|
|
console.info('连接成功.');
|
|
|
|
|
this.count = 0;
|
|
|
|
|
this.status = true;
|
|
|
|
|
|
|
|
|
|
// 恢复订阅
|
|
|
|
|
if (this.topic && this.onmessage) {
|
|
|
|
|
this.unsubscribe(this.topic);
|
|
|
|
|
this.subscribe(this.topic, this.onmessage, this.headers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检测sock是否断开
|
|
|
|
|
if (!this.clientIns.ws.onclose) {
|
|
|
|
|
this.clientIns.ws.onclose = () => {
|
2019-09-03 10:45:58 +08:00
|
|
|
|
checkLoginLine().then(() => {
|
|
|
|
|
this.status = false;
|
|
|
|
|
this.count++;
|
|
|
|
|
this.reconnect(this.count);
|
2019-09-03 16:13:23 +08:00
|
|
|
|
}).catch((err) => {
|
|
|
|
|
this.logOut(err);
|
2019-09-03 10:45:58 +08:00
|
|
|
|
});
|
2019-07-02 16:29:52 +08:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 定时器检测网络
|
|
|
|
|
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) => {
|
2019-09-03 16:13:23 +08:00
|
|
|
|
this.logOut(err);
|
2019-07-02 16:29:52 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}, 30000);
|
|
|
|
|
}
|
|
|
|
|
resolve(this);
|
|
|
|
|
}, () => {
|
2019-09-03 13:15:47 +08:00
|
|
|
|
if (this.checkTimer) {
|
|
|
|
|
clearInterval(this.checkTimer);
|
|
|
|
|
this.checkTimer = null;
|
|
|
|
|
}
|
2019-09-03 10:45:58 +08:00
|
|
|
|
checkLoginLine().then(() => {
|
|
|
|
|
this.connect();
|
2019-09-03 16:13:23 +08:00
|
|
|
|
}).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 + handleToken();
|
|
|
|
|
this.connect();
|
|
|
|
|
}
|
2019-09-03 10:45:58 +08:00
|
|
|
|
});
|
2019-07-02 16:29:52 +08:00
|
|
|
|
});
|
|
|
|
|
} catch (err) {
|
|
|
|
|
reject(err);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
},
|
2019-09-03 16:13:23 +08:00
|
|
|
|
logOut(err) {
|
|
|
|
|
if (err.code == 40003 || err.code == 40004 || err.code == 40005 || err.code == 50012) {
|
|
|
|
|
MessageBox.confirm('你已被登出,请重新登录', '确定登出', {
|
|
|
|
|
confirmButtonText: '重新登录',
|
|
|
|
|
showCancelButton: false,
|
|
|
|
|
type: 'warning'
|
|
|
|
|
}).then(() => {
|
|
|
|
|
store.dispatch('FedLogOut', gainClientId()).then(() => {
|
|
|
|
|
location.reload();// 为了重新实例化vue-router对象 避免bug
|
|
|
|
|
});
|
2019-09-03 10:45:58 +08:00
|
|
|
|
});
|
2019-09-03 16:13:23 +08:00
|
|
|
|
}
|
|
|
|
|
if (err.code == 50008 || err.code == 50014) {
|
|
|
|
|
this.url = websocketUrl + handleToken();
|
|
|
|
|
this.status = false;
|
|
|
|
|
this.count++;
|
|
|
|
|
this.reconnect(this.count);
|
|
|
|
|
}
|
2019-09-03 10:45:58 +08:00
|
|
|
|
},
|
2019-07-02 16:29:52 +08:00
|
|
|
|
// 恢复链接
|
|
|
|
|
reconnect(count) {
|
|
|
|
|
console.info(`尝试第${count || 1}次连接.`);
|
|
|
|
|
this.connect().then(() => { }).catch(() => {
|
|
|
|
|
this.count++;
|
|
|
|
|
this.reconnect(this.count);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
closeStompDebug() {
|
|
|
|
|
if (this.clientIns) {
|
|
|
|
|
this.clientIns.debug = undefined;
|
2019-08-12 11:01:00 +08:00
|
|
|
|
if (isDev) {
|
2019-07-02 16:29:52 +08:00
|
|
|
|
this.clientIns.debug = function (message) {
|
|
|
|
|
console.debug(message);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 订阅指定的topic
|
|
|
|
|
subscribe(topic, onmessage, headers) {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.subscribe(topic, onmessage, headers);
|
|
|
|
|
}, 300);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
unsubscribe(topic) {
|
|
|
|
|
if (this.subscribeMap) {
|
2019-08-12 11:01:00 +08:00
|
|
|
|
const subscription = this.subscribeMap.get(topic);
|
2019-07-02 16:29:52 +08:00
|
|
|
|
if (subscription) {
|
|
|
|
|
subscription.unsubscribe();
|
|
|
|
|
this.subscribeMap.delete(topic);
|
2019-08-12 11:01:00 +08:00
|
|
|
|
console.log('取消订阅');
|
2019-07-02 16:29:52 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 发送消息
|
|
|
|
|
send(url, msg) {
|
|
|
|
|
if (this.status) {
|
|
|
|
|
try {
|
|
|
|
|
this.clientIns.send(url, {}, msg);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.status = false;
|
|
|
|
|
this.send(url, msg);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.send(url, msg);
|
|
|
|
|
}, 300);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
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;
|
2019-08-12 11:01:00 +08:00
|
|
|
|
console.log('断开连接');
|
2019-07-02 16:29:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default StompClient;
|