rt-sim-training-client/src/utils/sock.js

187 lines
6.3 KiB
JavaScript
Raw Normal View History

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