zoukankan      html  css  js  c++  java
  • 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);
    		}
    	}
    }
    
  • 相关阅读:
    测试平台系列(9) 与前端联调注册/登录接口(part 2)
    测试平台系列(8) 与前端联调注册/登录接口(part 1)
    测试平台系列(7) 改造注册接口
    测试平台系列(6) 配置flask-sqlalchemy
    测试平台系列(5) 引入Ant Design Pro
    UICollectionView添加headerView
    iOS UICollectionReusableView xib 拖不了线
    xcode Errors were encountered while preparing your device for development. P
    UICollectionView Cell大小自适应 并靠左对齐最简单的实现
    iOS UICollectionView 一行三个计算 高度
  • 原文地址:https://www.cnblogs.com/raymondking123/p/11369723.html
Copyright © 2011-2022 走看看