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.3 KiB
170 lines
4.3 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()
|
|
|