import {showToast} from "@/utils/app"; import config from "@/utils/config"; import {logs} from "@/utils/util"; import store from "@/store"; export class Socket { constructor() { this.socketTask = null this.connectRun = false this.isOpen = false //避免重复连接 this.option = { connectNum: 1,// 重连次数 connectMaxNum: 3,// 重连最大次数 reconnectTime: 3000,// 重连最大间隔时间 heartInterval: 15000, // 心跳间隔 } this.followFlake = false // followFlake == true 重连 //心跳检测 this.heartbeatInterval = null //检测服务器端是否还活着 this.reconnectTimeOut = null //重连之后多久再次重连 this.connectList = {} this.openFun = {} this.messageFun = {} this.closeFun = {} } // 进入这个页面的时候创建websocket连接【整个页面随时使用】 async connect() { return new Promise(async (resolve, reject) => { if (this.socketTask || this.connectRun) { resolve() return; } let that = this this.connectRun = true try { this.socketTask = uni.connectSocket({ url: config.get('socketWss') + `?form=teacher&token=${store.getters['user/loginToken']}`, // header: { // // 'content-type': 'application/json', // form: 'teacher', // token: store.getters['user/loginToken'], // }, success: () => { logs("正准备建立websocket中..."); // 返回实例 }, fail: (err) => { logs("× 建立websocket失败"); reject() // 返回实例 }, }); this.socketTask.onOpen((res) => { console.log('onOpen', res) this.option.connectNum = 1 logs("WebSocket连接正常!"); clearInterval(this.reconnectTimeOut) clearInterval(this.heartbeatInterval) this.isOpen = true; this.start(); resolve() }) this.connectRun = false this.socketTask.onMessage(async (e) => { // 字符串转json let res = JSON.parse(e.data); // if (res.type != 'ping') logs("res---------->", res) // 这里 查看 推送过来的消息 let k = res.type if (k) { let key = this.connectList[k] if (!key) return let fun = this.messageFun[key] if (fun) await fun(res) } else { console.log('未知内容', res) } }); // 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接 this.socketTask.onError((res) => { logs('WebSocket连接打开失败,请检查!', res); // this.socketTask = null // this.isOpen = false; // uni.$off('getPositonsOrder') // if (!this.isOpen) { // if (this.option.connectNum < this.option.connectMaxNum) { // uni.showToast({ // title: `WebSocket连接失败,正尝试第${this.option.connectNum}次连接`, // icon: "none" // }) // this.reconnect(); // this.option.connectNum += 1 // } else { // // uni.$emit('connectError'); // this.reconnect(false); // } // } }); // 这里仅是事件监听【如果socket关闭了会执行】 this.socketTask.onClose(async () => { logs("socketTask 已经被关闭了-------") clearInterval(this.heartbeatInterval) clearInterval(this.reconnectTimeOut) this.socketTask = null this.isOpen = false; for (const k in that.closeFun) { that.closeFun[k]() } }) } catch (e) { } }) } // 主动关闭socket连接 close() { if (!this.socketTask) return this.socketTask.close({ success() { showToast('SocketTask 关闭成功') } }); } //发送消息 send(data, success = null, fail = null) { // 注:只有连接正常打开中 ,才能正常成功发送消息 if (this.socketTask && this.isOpen) { this.socketTask.send({ data: JSON.stringify(data), async success() { if (success) success() }, async fail(e) { console.error(`推送服务器失败:${e}`) if (fail) fail() }, }); } } //开启心跳检测 start() { this.heartbeatInterval = setInterval(() => { this.send({ "type": "ping" }); }, this.option.heartInterval) // 重连 for (const k in this.openFun) { this.openFun[k]() } } //重新连接 reconnect(run = true) { //停止发送心跳 clearInterval(this.heartbeatInterval) //如果不是人为关闭的话,进行重连 clearTimeout(this.reconnectTimeOut) this.reconnectTimeOut = null if (run && !this.isOpen && !this.connectRun) { this.reconnectTimeOut = setTimeout(() => { this.connect(); }, this.option.reconnectTime) } else if (!run) { this.option.connectNum = 1 } } stopHeartRate() { clearInterval(this.heartbeatInterval) } addConnect(type, key) { this.connectList[type] = key } delConnect(deviceId) { if (this.connectList[deviceId]) delete this.connectList[deviceId] } // init() { // if (this.connectState) return; // let socketWss = config.get('socketWss') // if (!socketWss) return; // this.username = store.getters['user/username'] // let that = this // let connectSocket = uni.connectSocket({ // url: socketWss, // header: { // 'content-type': 'application/json' // }, // }); // uni.onSocketOpen(function (res) { // that.connect = connectSocket // that.connectState = !0 // showSuccess('投影成功') // that.sendMessage({ // cmd: 'login', // port: 'TeacherPc', // username: that.username, // }) // }); // uni.onSocketError(function (res) { // showToast('连接实时投影展示失败') // that.connectState = !1 // }); // uni.onSocketMessage(function (res) { // if (!res.data) return; // let {code, data, msg} = JSON.parse(res.data) // logs('onSocketMessage', res.data) // if (code == 50003) { // that.sendMessage({ // cmd: 'online' // }) // } else { // logs('onSocketMessage', code, data, msg) // } // }); // } // // /** // * 发送信息 // * @param data // */ // sendMessage(data = {}) { // if (!this.connectState) return; // uni.sendSocketMessage({ // data: JSON.stringify(data) // }); // } // // /** // * 关闭连接 // */ // closeSocket() { // if (!this.connectState) return; // uni.closeSocket() // } }