Unity进阶之ET网络游戏开发框架 07-修正游客登录的异步BUG
2024-08-29 07:53:39
版权申明:
- 本文原创首发于以下网站:
- 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123
- 优梦创客的官方博客:https://91make.top
- 优梦创客的游戏讲堂:https://91make.ke.qq.com
- 『优梦创客』的微信公众号:umaketop
- 您可以自由转载,但必须加入完整的版权声明!
由来
- 我的上一篇博文中的OnStartClick方法采用的是async异步方法,但是由于微软并未保证async创建的方法一定在其调用线程中执行,所以不能保证程序是单线程的
- ET整个框架都是基于多进程单线程这一设计思想的(为了避免多线程带来的性能损失和逻辑错误),所以为了避免async造成的多线程陷阱,ET自定义了一套多线程任务系统,其返回值类型都是以ET开头的,例如:
- Task → ETTask
- void → ETVoid
- Task → ETTask
- ET作者说过这么一句话:async方法的返回值永远不要用.NET原生的Task,全部采用ETTask
- 配套的,我们需要修改原有的代码,如下:
public class MyStartUIComponent : Component
{
GameObject goStartButton;
public void OnAwake()
{
var rc = this.Parent.GameObject.GetComponent<ReferenceCollector>();
goStartButton = rc.Get<GameObject>("StartButton");
goStartButton.GetComponent<Button>().onClick.AddListener(OnStartClick);
}
private void OnStartClick()
{
// Coroutine()方法模拟将OnStartClickAsync()作为协程执行的效果(确保在单线程中执行)
OnStartClickAsync().Coroutine();
}
private async ETVoid OnStartClickAsync()
{
// 处理游客登录点击
try
{
// 1: 创建一个realmSession,并利用此session去call一个rpc消息(模型层session表示具体网络参数和连接,热更层负责通信逻辑,它调用模型层)
ETModel.Session session = ETModel.Game.Scene.GetComponent<NetOuterComponent>().Create(GlobalConfigComponent.Instance.GlobalProto.Address);
Session realmSession = ComponentFactory.Create<Session, ETModel.Session>(session);
// 2:若登录失败,会收到异常;若成功,则会得到认证信息(模型层没有C2R_Login的类定义,所以必须配套由热更层的session去call)
var r2cLogin = await realmSession.Call(new C2R_Login()
{
Account = Guid.NewGuid().ToString(),
Password = "111111",
}) as R2C_Login;
// 3:再利用此认证信息中的网关服务器地址,去创建gateSession
session = ETModel.Game.Scene.GetComponent<NetOuterComponent>().Create(r2cLogin.Address);
Session gateSession = ComponentFactory.Create<Session, ETModel.Session>(session);
// 4:用gateSession去登录gate服(传入登录key)
var g2cLoginGate = await gateSession.Call(new C2G_LoginGate()
{
Key = r2cLogin.Key
}) as G2C_LoginGate;
// 5:登录成功后,用返回的playerId,创建Player对象
var p = ETModel.ComponentFactory.CreateWithId<Player>(g2cLoginGate.PlayerId);
ETModel.Game.Scene.GetComponent<PlayerComponent>().MyPlayer = p;
// 6:发送登录完成事件
Game.EventSystem.Run(MyEventType.MyLoginFinish);
}
catch (Exception e)
{
Log.Error(e);
}
}
}
最新文章
- 【AspNet Core】Nuget代理网站
- 如何重新划分linux分区大小
- WPF ListBox响应鼠标滚轮
- pandas groupby
- javascript AOP实现
- hdu 4405 Aeroplane chess(简单概率dp 求期望)
- random随机函数
- cas sso单点登录系列2:cas客户端和cas服务端交互原理动画图解,cas协议终极分析
- [Leetcode][Python]25: Reverse Nodes in k-Group
- uml系列(六)——行为图:活动&;状态
- 解决ssh连接linux服务器速度慢
- kettle并行运行时出现「Unknown error in KarafBlueprintWatcher」
- thinkcmf 相关
- text2
- POJ Lost Cows
- T-SQL中的十大注意事项
- 《A_Pancers》团队作业6—团队项目系统设计改进与详细设计
- Json学习一(基础概念知识学习)
- Mac OS X 10.11.1下搭建Python3.4 + PyQt5.5.1 +Eric6.1.1开发平台
- Downgrading an Exchange 2010 Server(Exchange降级)
热门文章
- Netty学习-IO体系架构系统回顾 &; 装饰模式Decorator的具体使用
- 手把手教你创建electron+vue项目
- nginx 进程问题
- [转帖]POW , POS 与 DPOS 一切都为了共识
- LInux因为缺失网关出现Name or service not known的解决方法
- Vue框架(三)——Vue项目搭建和项目目录介绍、组件、路由
- js拼接url以及为html某标签属性赋值
- 【翻译】REST framework JWT Auth(django rest framework-jwt)
- CentOS7安装Prometheus(二进制)
- Spark实战电影点评系统(二)