rt-sim-training-client/src/utils/sock.js
2020-07-10 11:26:15 +08:00

203 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { getToken } from '@/utils/auth';
import { checkLoginLine } from '@/api/login';
import { getBaseUrl } from '@/utils/baseUrl';
import { MessageBox } from 'element-ui';
import store from '@/store/index_APP_TARGET';
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
const isDev = process.env.NODE_ENV === 'development';
const isTest = process.env.NODE_ENV === 'test';
const websocketUrl = `${getBaseUrl()}/joylink-websocket?token=`;
const reconnectInterval = [1000, 3000, 5000, 10000, 30000, 60000];
let notFirstConnect = false;
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,
url: '',
status: false,
sockStatus: 0,
headers: {
// 'X-Token': getToken()
},
isPassived:true, // 是否被动断线重连
// isconnect:true,
count: 0,
topic: '',
onmessage: null,
// 连接服务端
connect() {
return new Promise((resolve, reject) => {
try {
// 建立连接对象(还未发起连接)
// null, {transports:['websocket']}虽可以解决连接关闭后xhr_streaming无限循环
// 但是该参数只会允许websockets,若不支持,直接报错
// 注意sockjs会做降级处理优先处理websockets若浏览器不支持websockets
// 则会降级为xhr_streaming轮询继续不支持的时候会降级为xhr-polling
this.socket = new SockJS(websocketUrl + getToken());
// 获取 STOMP 子协议的客户端对象
this.clientIns = Stomp.over(this.socket);
this.closeStompDebug();
// const oldtransportClose = SockJS.prototype._transportClose;
// SockJS.prototype._transportClose = function(code, reason) {
// // To do
// // ...
// console.log(reason + '-----------------', this._transport);
// if (this._transport && this._transport.close) {
// this._transport.close();
// }
// return oldtransportClose.call(this, code, reason);
// };
// 向服务器发起websocket连接并发送CONNECT帧
const that = this;
this.clientIns.connect({ 'X-Token': getToken() }, () => {
if (notFirstConnect) {
// setTimeout(()=>{ Message.success('连接成功'); });
}
console.info('连接成功.');
that.count = 0;
that.status = true;
// 恢复订阅
that.subscribeMap.forEach((subscribe) => {
that.subscribe(subscribe.dest, subscribe.handler);
});
// sock断开回调
that.clientIns.ws.onclose = () => {
// Message.error(`通信连接已断开!`);
notFirstConnect = true;
checkLoginLine().then(() => {
that.status = false;
that.count++;
that.reconnect(that.count);
}).catch((err) => {
that.logOut(err);
});
};
resolve(this);
}, () => {
if (this.isPassived) {
checkLoginLine().then(() => {
this.count++;
this.reconnect(this.count);
}).catch((err) => {
this.logOut(err);
});
}
});
} catch (err) {
reject(err);
}
});
},
logOut(err) {
console.info(err);
MessageBox.confirm('你已被登出,请重新登录', '确定登出', {
confirmButtonText: '重新登录',
showCancelButton: false,
type: 'warning'
}).then(() => {
store.dispatch('FedLogOut').then(() => {
location.reload();// 为了重新实例化vue-router对象 避免bug
});
});
},
// 恢复链接
reconnect(count) {
console.info(`尝试第${count || 1}次连接.`);
// Message.warning(`正在尝试第${count || 1}次通讯连接。`);
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) {
if (isDev || isTest) {
this.clientIns.debug = function (message) {
console.debug(message);
};
}
}
},
// 订阅指定的topic
subscribe(topic, onmessage, headers) {
// const timeDelay = [1000, 2000, 5000, 10000];
this.topic = topic;
this.onmessage = onmessage;
this.headers = headers;
if (!this.status) {
this.subscribeMap.set(topic, {dest: topic, handler: onmessage, sub: null});
} else {
const sub = this.clientIns.subscribe(topic, onmessage);
this.subscribeMap.set(topic, {dest: topic, handler: onmessage, sub: sub});
}
},
unsubscribe(topic) {
const subscription = this.subscribeMap.get(topic);
if (subscription && subscription.sub) {
subscription.sub.unsubscribe();
this.subscribeMap.delete(topic);
console.log('取消订阅:' + topic);
} else if (subscription) {
this.subscribeMap.delete(topic);
}
},
// 发送消息
send(url, msg) {
if (this.status) {
if (msg) {
msg = JSON.stringify(msg);
this.clientIns.send(url, {}, msg);
} else {
console.error('发送消息为空');
}
} else {
setTimeout(() => {
this.send(url, msg);
}, 300);
}
},
disconnect() {
if (this.clientIns) {
if (this.clientIns.connected) {
this.clientIns.disconnect();
}
this.isPassived = false;
this.socket.close();
this.socket = null;
this.clientIns = null;
}
this.status = false;
console.info('断开连接');
}
};
export default StompClient;