import Setting from "@/setting"; import th from "element-ui/src/locale/lang/th"; const MAX_ERROR_NUMBER = 1000; class Socket { constructor() { this.timer = null; //心跳定时器 this.connectStatus = false; //连接状态 this.reconnectTimer = 2000; //重连 this.handClse = false; //手动关闭 this.reconnetime = null; //重连 定时器 this.networkStatus = true; this.connectLing = false; //连接是否进行中 this.ws = null; this.vm = null; this.token = null; this.errorNumber = 0 } wss(wsSocketUrl) { let ishttps = document.location.protocol == "https:"; if (ishttps) { return wsSocketUrl.replace("ws:", "wss:"); } else { return wsSocketUrl.replace("wss:", "ws:"); } } startConnect(){ if (!this.connectStatus && !this.connectLing) { let strategy = this.vm.$auth.$storage.getCookie("strategy"), token; if (this.vm.$auth.$storage.getCookie(`_token.${strategy}`)) { token = this.vm.$auth.$storage.getCookie(`_token.${strategy}`).split(" ")[1]; } this.errorNumber = 0; this.connect(token); } } connect(token) { if (token === undefined) { return; } let wsUrl = Setting.wsSocketUrl // 判断是否是客户端 if (process.browser) { // 是否已存服务器状态 if (sessionStorage.getItem("SERVER_TYPE") !== 'nginx') { wsUrl = wsUrl + '/ws' } } this.token = token; this.ws = new WebSocket(this.wss(wsUrl) + '?type=user' + '&token=' + token); this.ws.onopen = this.onOpen.bind(this); this.ws.onerror = this.onError.bind(this); this.ws.onmessage = this.onMessage.bind(this); this.ws.onclose = this.onClose.bind(this); this.connectLing = true; } setVm(vm) { this.vm = vm; } close() { } onOpen() { this.ping(); this.reconnetime = null; this.connectLing = false; this.connectStatus = true; this.errorNumber = 0; this.vm.$emit("socket-open"); } ping() { var that = this; this.timer = setInterval(() => { that.send({type: "ping"}); }, 10000); } send(data) { let that = this; //没有网络,或者没有连接 if (!this.connectStatus || !this.networkStatus) { this.reconne(); } return new Promise((reslove, reject) => { try { this.ws.send(JSON.stringify(data)); reslove(); } catch (e) { if (e == 'sendSocketMessage:fail WebSocket is not connected' || e == 'sendSocketMessage:fail Error: SocketTask.readyState is not OPEN' ) { that.reconne(); } reject(e); } }) } onMessage(res) { const {type, data = {}} = JSON.parse(res.data); if (type === "chat" || type === 'reply') { this.vm.chat(data); } if (type == "to_transfer") { this.vm.toTransfer(data); } // this.vm.$emit(type, data); } onClose() { console.log('关闭连接') this.vm.$emit('close'); //手动关闭不用重新连接 if (this.handClse) { return; } clearInterval(this.timer); this.timer = null; this.connectStatus = false; this.connectLing = false; this.reconne(); } onError(e) { console.log('连接发生错误', e) this.connectStatus = false; this.connectLing = false; this.reconne(); this.vm.$emit("socket-error", e); } //断线重连 reconne() { //没有token的情况下。不用重新连接 if (this.token === null) { return; } if (this.reconnetime || this.connectStatus || this.errorNumber > MAX_ERROR_NUMBER) { return; } this.reconnetime = setInterval(() => { if (this.connectStatus) { return; } if (!this.connectLing) { this.connect() this.errorNumber++ } }, this.reconnectTimer); } } export default Socket;