rt-sim-training-client/src/utils/sock.js
2019-11-18 14:29:43 +08:00

251 lines
8.0 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';
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 websocketUrl = `${getBaseUrl()}/joylink-websocket?token=`;
// const websocketUrl = `http://192.168.3.6:9000/joylink-websocket?token=`;
var StompClient = function (headers) {
this.url = websocketUrl + getToken();
this.headers = headers || {};
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());
// 获取 STOMP 子协议的客户端对象
this.clientIns = Stomp.over(this.socket);
this.closeStompDebug();
// 向服务器发起websocket连接并发送CONNECT帧
this.clientIns.connect({ 'X-Token': getToken() }, () => {
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 = () => {
checkLoginLine().then(() => {
this.status = false;
this.count++;
this.reconnect(this.count);
}).catch((err) => {
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();
}
});
});
} catch (err) {
reject(err);
}
});
},
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').then(() => {
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);
});
},
closeStompDebug() {
if (this.clientIns) {
this.clientIns.debug = undefined;
if (isDev) {
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) {
const subscription = this.subscribeMap.get(topic);
if (subscription) {
subscription.unsubscribe();
this.subscribeMap.delete(topic);
console.log('取消订阅');
}
}
},
// 发送消息
send(url, msg) {
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 {
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;
console.log('断开连接');
}
};
export default StompClient;