You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

170 lines
4.2 KiB

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()