2022-12-06 23:10:03 +08:00

116 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Singleton from '../Base/Singleton'
import { ApiMsgEnum, IModel, strdecode, strencode } from '../Common';
import { binaryEncode, binaryDecode } from '../Common/Binary';
const TIMEOUT = 5000
export interface ICallApiRet<T> {
success: boolean;
error?: Error;
res?: T
}
type aaa = keyof IModel
export default class NetworkManager extends Singleton {
static get Instance() {
return super.GetInstance<NetworkManager>()
}
ws: WebSocket
port = 8888
maps: Map<ApiMsgEnum, Function[]> = new Map()
isConnected = false
connect() {
return new Promise((resolve, reject) => {
if (this.isConnected) {
resolve(true)
return
}
this.ws = new WebSocket(`ws://localhost:${this.port}`)
this.ws.binaryType = 'arraybuffer';
this.ws.onopen = () => {
console.log("ws onopen")
this.isConnected = true
resolve(true)
}
this.ws.onerror = () => {
this.isConnected = false
reject("ws onerror")
}
this.ws.onclose = () => {
this.isConnected = false
reject("ws onclose")
}
this.ws.onmessage = (e) => {
try {
const json = binaryDecode(e.data)
const { name, data } = json
try {
if (this.maps.has(name) && this.maps.get(name).length) {
console.log(json);
this.maps.get(name).forEach(cb => cb(data))
}
} catch (error) {
console.log("this.maps.get(name).forEach(cb => cb(restData))", error)
}
} catch (error) {
console.log('解析失败不是合法的JSON格式', error)
}
}
})
}
callApi<T extends keyof IModel['api']>(name: T, data: IModel['api'][T]['req']): Promise<ICallApiRet<IModel['api'][T]['res']>> {
return new Promise((resolve) => {
try {
// 超时处理
const timer = setTimeout(() => {
resolve({ success: false, error: new Error('timeout') })
this.unlistenMsg(name, cb)
}, TIMEOUT)
// 回调处理
const cb = (res) => {
resolve(res)
clearTimeout(timer)
this.unlistenMsg(name, cb)
}
this.listenMsg(name as any, cb)
this.sendMsg(name as any, data)
} catch (error) {
console.log(error)
resolve({ success: false, error: error as Error })
}
})
}
async sendMsg<T extends keyof IModel['msg']>(name: T, data: IModel['msg'][T]) {
const view = binaryEncode(name, data)
let networkLag = parseInt(new URLSearchParams(location.search).get('lag') || '0') || 0;
await new Promise((r) => setTimeout(r, networkLag))
this.ws.send(view.buffer)
}
listenMsg<T extends keyof IModel['msg']>(name: T, cb: (args: IModel['msg'][T]) => void) {
if (this.maps.has(name)) {
this.maps.get(name).push(cb)
} else {
this.maps.set(name, [cb])
}
}
unlistenMsg(name: ApiMsgEnum, cb: Function) {
if (this.maps.has(name)) {
const index = this.maps.get(name).indexOf(cb)
index > -1 && this.maps.get(name).splice(index, 1)
}
}
}