Unity进阶之ET网络游戏开发框架 07-修正游客登录的异步BUG

版权申明:

  • 本文原创首发于以下网站:
  1. 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123
  2. 优梦创客的官方博客:https://91make.top
  3. 优梦创客的游戏讲堂:https://91make.ke.qq.com
  4. 『优梦创客』的微信公众号: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);
        }
    }
}

转载于:https://www.cnblogs.com/raymondking123/p/11369723.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值