Просмотр исходного кода

Merge pull request #23 from MrTigerZhang/MrTigerZhang-patch-1

Create 网络组件学习笔记.MD
tanghai 8 лет назад
Родитель
Сommit
e87e8bdfe5
1 измененных файлов с 59 добавлено и 0 удалено
  1. 59 0
      Doc/网络组件学习笔记.MD

+ 59 - 0
Doc/网络组件学习笔记.MD

@@ -0,0 +1,59 @@
+# 在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。
+
+
+
+