import { eg } from "../frameWork/eg"; import { GameServerConfig } from "../network/GameServerConfig"; import { HttpClient as HttpClient_Browser, TsrpcError, WsClient as WsClient_Browser } from 'tsrpc-browser'; import { HttpClient as HttpClient_Miniapp, WsClient as WsClient_Miniapp } from 'tsrpc-miniapp'; import { serviceProto as ServiceProtoRoom, ServiceType, ServiceType as ServiceTypeRoom } from "../shared/serviceProto"; import IDataModel from "../frameWork/model/IDataModel"; import UIHelp, { DialogParams } from "../logic/ui/UIHelp"; import GameController from "../GameController"; import { I18n } from "../utils/I18nUtil"; import { NetworkEvent } from "../data/const/EventConst"; import EventMng from "../manager/EventMng"; import GameDataCenter from "../data/GameDataCenter"; import { Code } from "../shared/base"; /** 游戏服 */ export class GameServerModel extends IDataModel { /** 连接房间服务器 Websocket 客户端 */ wscRoom: WsClient_Miniapp | WsClient_Browser = null!; /** 重连次数 */ reconnectCnt: number = 0; async Init(serverUrl: string) { this.wscRoom = eg.tspcNet.createWscRoom(serverUrl); } /** 连接游戏服 */ async Connect() { let resConnect = await this.wscRoom.connect(); if (!resConnect.isSucc) { console.error('连接游戏服失败', resConnect.errMsg); return; } CC_PREVIEW && console.log('连接游戏服成功'); this.PostDisconnectFlow(); } /** 重连游戏服 */ async ReConnect() { this.reconnectCnt++; let resConnect = await this.wscRoom.connect(); if (!resConnect.isSucc) { console.log('连接游戏服失败', resConnect.errMsg); if (this.reconnectCnt >= GameServerConfig.reconnectMax) { CC_PREVIEW && console.error("重连服务器超过上限"); let dialogParam: DialogParams = { content: I18n.getI18nText("http_overtime"), cbConfirm: () => { this.reconnectCnt = 0; GameController.clear(); cc.game.restart(); }, txtConfirm: I18n.getI18nText("http_overtime_confirm_1"), onlyConfirm: true } UIHelp.ShowSystemDialog(dialogParam) return; } setTimeout(() => { this.ReConnect(); }, 2000); return; } EventMng.emit(NetworkEvent.WAIT, -1) CC_PREVIEW && console.log("重连服务器成功"); GameDataCenter.login.sendEnterGame(GameDataCenter.login.playerInfo.sid) } /** 客户端与服务器断开事件 */ private PostDisconnectFlow() { this.wscRoom.flows.postDisconnectFlow.push(v => { // 非客户端手动断开时处理(例:网络错误、服务器关闭) if (!v.isManual) { CC_PREVIEW && console.log("wss断线", v.reason); EventMng.emit(NetworkEvent.WAIT, 1); this.reconnectCnt = 0; // 等待 2 秒后自动重连 this.ReConnect(); } return v; }); } /** 错误处理 */ private ErrorHandler(err: TsrpcError) { if (err) { UIHelp.ShowTips(err.message); switch (err.code) { case Code.fail: UIHelp.ShowTips(err.message); break; } return null; } } /** 请求api */ public async ReqApi(apiName: T, req: ServiceType['api'][T]['req']) { let ret = await this.wscRoom.callApi(apiName, req); if (!ret.isSucc) { this.ErrorHandler(ret.err) return null; } return ret; } /** ws发送消息 */ public SendMsg(msgName: T, msg: ServiceType['msg'][T]) { this.wscRoom.sendMsg(msgName, msg); } /** 监听消息 */ public ListenMsg(msgName: T | RegExp, callback: Function, target: any) { this.wscRoom.listenMsg(msgName, v => { callback.call(target, v); }); } }