import { director, EventTarget } from "cc"; import { _decorator, Component, Node } from "cc"; import { PogWebsocketListener as IWebsocketMessage, PogWebsocket, } from "./PogWebsocket"; import JsonUtils from "../utils/JsonUtils"; const { ccclass, property } = _decorator; export class WsResponse { protocolId: number; requestId: number; code: number; success: boolean; data: any; msg: string; } export class WsRequest { requestId: number; protocolId: number; data: any; public static create(protocolId: number): WsRequest { let msg = new WsRequest(); msg.protocolId = protocolId; msg.requestId = Math.floor(Math.random() * 1000000); msg.requestId = 2; return msg; } public setData(data: any): WsRequest { this.data = data; return this; } public async send() { let data = JSON.stringify(this); // data = this.convertBigInt(data, ["familyId", "userId"]); // console.log("send", data); await WS.ins.send(data); } private convertBigInt(data: string, keys: string[]): string { // 将data中的keys转换为bigint // {"familyId":"123456789"} 去掉引號 {"familyId":123456789},使用正则表达式 let regex = /"([^"]+)":/g; let match = regex.exec(data); while (match) { let key = match[1]; let value = data.substring(match.index + match[0].length, data.indexOf(":", match.index + match[0].length)); data = data.replace(match[0], `"${key}":${value}`); match = regex.exec(data); } return data; } } @ccclass("WS") export class WS extends Component implements IWebsocketMessage { public disconnect() { if (this.pogWebsocket) { this.pogWebsocket.close(); } } OnMessage(data: any): void { // console.warn("onMessage", typeof data.data, data.data); if ("pong" == data) { return; } let msg: WsResponse = JsonUtils.parse(data.data); this._e.emit("" + msg.protocolId, msg); } init() {} onTimeout() { this.pogWebsocket.clearReconnectTimes(); this.pogWebsocket.reconnect(); } private _url: string = ""; private _token: string = ""; public async connect(url: string, token: string) { this._url = url; this._token = token; return new Promise((resolve) => { try { let full_url = `${url}?accessToken=${token}`; this.pogWebsocket = PogWebsocket.create(full_url, this); resolve(true); } catch (e) { console.error(e); resolve(false); } }); } private static _ins: WS; private pogWebsocket: PogWebsocket; public static get ins(): WS { return (this._ins ??= new WS()); } private _dt: number = 0; public update(dt: number) { this._dt += dt; if (this._dt > 5) { this._dt = 0; if (this.pogWebsocket) { this.pogWebsocket.ping(); } } } public async send(msg: any) { console.log("send", msg); for (let i = 0; i < 3; i++) { if (!this.pogWebsocket.connected) { await new Promise((resolve) => setTimeout(resolve, 500)); } } return await this.pogWebsocket.send(msg); } public close() { this.pogWebsocket.close(); } private _e: EventTarget; protected onLoad(): void { WS._ins = this; this._e = new EventTarget(); this.node.parent = null; director.getScene().addChild(this.node); director.addPersistRootNode(this.node); } public on( protocolId: number, handler: (...args: any[]) => void, target: any ) { this._e.on("" + protocolId, handler, target); } public off( protocolId: number, handler: (...args: any[]) => void, target: any ) { this._e.off("" + protocolId, handler, target); } protected onDestroy(): void { // console.log("WS onDestroy"); } }