import EventEmitter from "./events.js" export class Msg{ data = "" // 数据载体 ev = "" // 事件类型 _success = 0 // 是否发送成功 constructor(ev, data, _success) { this.ev = ev; this.data = data; this._success = _success; } } Msg.create = function(ev, data, _success){ return new Msg(ev, data, _success) } Msg.clone = function(data, _success){ return new Msg(data.ev, data.data, _success!=undefined ? _success : data._success) } class Sc { #isConnected = false; #isConnecting = false; // #url = "ws://82.157.123.54:9010/ajaxchattest" #url = "ws://127.0.0.1:8888" #instance = null #event = null #isClose = false #time = 0 // 重连的次数 #maxTime = 10 // 能够重连的次数 #timerID = -1 // 心跳检测 // WILL: 是否需要检测心跳检测没回应的次数断开连接 #heartTimes = 0 // 心跳检测次数 constructor() { this.#event = new EventEmitter() } get event(){ return this.#event; } close(){ if(!this.#isConnected) return if(!this.#instance) return this.#isClose = true this.#instance.close() } /** * 心跳检测 */ heartTime(){ if(!this.#isConnected) return if(!this.#instance) return if(this.#timerID!=-1) return this.send({ping: new Date().getTime()}, true) this.#timerID = setInterval(()=>{ this.send({ping: new Date().getTime()}, true) },5000) } clearHeartTime(){ clearInterval(this.#timerID) this.#timerID = -1 } send(data, isPing){ return new Promise((resolve,reject)=>{ const that = this; if(!data instanceof Msg || isPing) { console.error("载体不是msg实例") return } if(this.#isConnected){ const encryptData = encodeURIComponent(JSON.stringify(data)); this.#instance.send({ data: encryptData, success(){ resolve() }, fail() { that.#event.emit('onMessage',Msg.clone(data,2)) // reject() resolve() } }); }else{ that.#event.emit('onMessage',Msg.clone(data,2)) // reject() resolve() } }) } initConnect(opts = {}, isReConnect) { if(typeof opts === "boolean"){ isReConnect = opts opts = {} } if(this.#isConnecting&&!isReConnect) return if (this.#isConnected) return this.#isConnecting = true this.#instance = uni.connectSocket({ url: this.#url, header: opts.header || {}, complete: () => {} }); const onError = (errMsg)=>{ // console.log(errMsg); } const onMessage = (data)=>{ // console.log(data); } const onOpen = async ()=>{ } const onClose = ()=>{ } this.#event.on('onMessage', onMessage) this.#event.on('onError', onError) this.#event.on('onOpen', onOpen) this.#event.on('onClose', onClose) this.#instance.onOpen(async ()=>{ this.#isConnected = true this.#isConnecting = false this.#time = 0 this.#event.emit('onMessage', Msg.create("msg","客户端已连接",1)) this.#event.emit('onOpen', isReConnect) this.heartTime() if(isReConnect){ this.send(Msg.create("reconnect",true,1)) } }) this.#instance.onClose(()=>{ this.#isConnected = false this.#isConnecting = false this.#instance = null this.clearHeartTime() this.#event.off("onClose", onClose) this.#event.off("onError", onError) this.#event.off("onOpen", onOpen) this.#event.off("onMessage", onMessage) if(!this.#isClose){ this.#time++ if(this.#time<=this.#maxTime){ this.#isConnecting = true setTimeout(()=>{ this.#event.emit('onMessage', Msg.create("msg",`第${this.#time}次重连`,1)) // 重连 this.initConnect(opts, true) },2000) }else{ this.#event.emit('onMessage', Msg.create("msg","客户端已离线,请重试",1)) this.#event.emit('onClose') } }else{ this.isClose = false this.#event.emit('onMessage', Msg.create("msg","客户端已离线",1)) this.#event.emit('onClose') } }) this.#instance.onError((errMsg)=>{ this.#event.emit('onError', errMsg) }) this.#instance.onMessage((data)=>{ // let rData = JSON.parse(decodeURIComponent(data.data).slice(0,-66)); let rData = JSON.parse(decodeURIComponent(data.data)); console.log(`原始数据:`,rData); if(rData.hasOwnProperty("ping")) return rData._success = rData._success == 0 ? 1 : rData._success this.#event.emit('onMessage',rData) }) } } export default new Sc()