ET网络组件学习笔记

在ET的客户端中,使用网络要用到以下几个组件(不介绍基础设施)。

组件名称 组件作用
OpcodeTypeComponent 消息类型加载组件。加载标记了【MessageAttribute】注解的类,作为消息执行的类型,并存储在这个组件的opcodeTypes字段下,提供后续方法使用。
MessageDispatcherComponent 消息分发组件,加载消息处理器。加载所有标记了【MessageHandlerAttribute】属性的类,并提供Handle方法,将传入的MessageInfo发送给指定的消息处理器
NetworkComponent NetworkComponent是其他上层网络访问组件的基类,这个类型在服务端和客端项目公用。用于 指定该协议、指定构包解析方式、指定消息转发器,开始socket监听、创建session。内部有一个AService字段。抽象了udp和tcp协议的连接工厂,用于创建channel使用tcp做服端的时候可以创建多个Session,每个Session都是一个连接的高层抽象。这个类型在服务端和客户端项目公用。其提供的MessageDispatch和MessagePacker仅在客户端项目使用。一个是客户端消息转发器,一个是客户端消息打包器。
NetOuterComponent 继承自NetworkComponent,用于对外网的连接。可以在Awake中指定协议,指定包解析器。客户端使用的session都是通过这个组件创建的。需要切换网络协议或者数据序列化方式就在这个组件的Awake方法中指定对应的参数就可以了。
SessionComponent SessionComponent 组件用于存储Seesion,目前客户端只会存在一个在用的session。登录后获得的GateSession会存储在这个组件中。会在之后的对服务器端的调用中使用这个session。
ClientFrameComponent 用于处理帧同步。

很重要的Session对象的解释

每个Session都是一个连接的高层抽象。
向session另一端做rpc调用可以调用它的Call方法,发送消息可以调用Send,
二者的区别在于是否需要服务器响应一个反馈消息。
定义消息或者rpc请求的时候使用Message标签设置消息类型与opcode的对应关系。
session是由NetworkComponent创建的,参数是 NetworkComponent的本类实例 + 用于收发字节码的AChannel实例。这个AChannel则是由NetworkComponent中的AService工厂创建的。

流程:

1创建session后(调用构造函数),session开始StartRecv()方法,这个方法循环通过异步方法调用channel的Recv()方法,接收链接另一端发来的数据。
2接收到消息后调用Run方法,run方法检查接收到的数据包是否有压缩,并指向相应的操作。
3处理完压缩解压操作后交给RunDecompressedBytes,该方法比较厉害,调用绑定在Scene实体上的NetWorkConponent上的注册的解包器(默认是Bson)解包。
4解包操作结束后就将其交给绑定在Scene实体上的NetWorkConponent上的messageDispatcher做转发。转发给相应的handler处理。

在大致了解了各组件的作用后,需要有一个大致的流程,把几个组件串联起来,实现客服端的网络功能:

网络流程如下:

1. OpcodeTypeComponent加载封装好的网络消息。

2. MessageDispatcherComponent加载所有的Handler

3. 开启网络监听。NetOuterComponent加入到Scene,我们使用udp,做如下操作:、

  • a) 通过工厂从对象池中取出实例,调用父类Disposer的构造方法,加入到对象事件中心。
  • b) 调用父类NetworkComponent的构造方法,创建对应协议的连接工厂(AService)。
  • c) 调用NetOuterComponent的Awake()方法,指定网络协议、消息解包器和消息转发器。
  • d) NetworkComponent因为注册了Update,所以会在每一帧执行Update,Update中会执行service的update。service的update中会执行poller的Update,这个Update实际上是 每一帧都要轮询出所有的主机上的队列事件,并且调用其委托。这些事件包括:开始连接、接收数据、断开连接。这些事件的触发,会调用poller实体上的socket的对应的响应方法。 socket事件的委托是在创建UChannel时注册的。
  • e) UChannel的OnRecv()将接受到的消息放入到队列中,等待被Session轮询调用UChannel. Recv()方法取出。
  • f) 取出消息后就会调用给NetOuterComponent指定的消息转发器。
    由于是客户端,所以使用ClientDispatcher作为消息转发器。这个消息转发器在接收到帧循环消息后会进行客户端时间补偿处理。否则就直接将普通的rpc等消息交给MessageDispatcherComponent去做转发了。当然,帧循环消息最终也会交给MessageDispatcherComponent做转发。
  • g) Handle接收到消息后作出最终的处理。
  • h) D-g步骤是循环执行滴。
  • i) 底层enet等不深入讨论,对我等透明。
  • j) 到此,网络设施已经创建完毕,网络监听已经开启,并等待使用。

4. 创建对外连接。创建对外连接指的是连接到服务器。一般情况下从登陆开始创建对外连接。并且存储会话Gatesession。在整个客户端游戏生命周期中,Gatesession是一直存在的而且只有一份。

  • a) 使用NetOuterComponent创建session。需指定要连接的地址和端口。这时候创建的session一般会是登录服务器,因为登录服务器在登录成功后会返回一个网关地址。
  • b) 然后再根据这个网关地址创建游戏使用的session并且存入到SessionComponent中。
  • c) SessionComponent要加入到Scene实体保存。

5. 使用session通讯。

  • a) await SessionComponent.Instance.Session.Call<G2C_LoginGate>(new C2G_LoginGate() {Key = r2CLogin.Key})
  • b) 详细参考doc中的《网络层设计》使用说明书。

6. 拓展网络功能以及建议。

  • a) 这个嘛,仁者见仁啦。
  • b) 注意。使用c#的异步语法实现异步网络调用,是一件很舒服的事情,请详细研究异步语法。并使用之。

- 登录流程示例讲解:

//TODO

在掌握了ET客户端网络功能之后基本就掌握了ET的客户端框架。其他的一些框架特性是为了增加功能方便开发,当然如果实在掌握不了或者不喜欢用某个组件,可以用其他的方式实现,比如那个行为树。当然,一定要举一反三,通过学习研究网络组件,对整个et框架有个更深的认识,能够理解组件设计模式的精髓。组件包含数据和功能、实体包含组件,逻辑就是整个系统调用组件的过程。这也是最近闹得沸沸扬扬的ECS。另外,此处只是客户端的逻辑,服务端的逻辑TODO。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,968评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,682评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,254评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,074评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,964评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,055评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,484评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,170评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,433评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,512评论 2 308
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,296评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,184评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,545评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,150评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,437评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,630评论 2 335

推荐阅读更多精彩内容

  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 4,961评论 0 9
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,065评论 1 32
  • 一. Java基础部分.................................................
    wy_sure阅读 3,774评论 0 11
  • https://nodejs.org/api/documentation.html 工具模块 Assert 测试 ...
    KeKeMars阅读 6,278评论 0 6
  • 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Se...
    chinariver阅读 5,570评论 1 49