关于GF的Network模块的一些见解。初步开始了解GF的网络模块。GF版本:3.1.0

1使用网络频道的流程
1.1创建一个网络频道帮助类,做消息的序列化和反序列化。需要继承INetworkChannelHelper,如果希望能在场景中看到。就需要再继承MonoBehaviour
1.1.1属性PacketHeaderLength,当前接收到消息包内容的消息包头长度,会从流(Stream source)中读取的字节长度。
1.1.2通过DeserializePacketHeader(Stream source, out object customErrorData)解析消息包头,source的内容长度就是PakcetHeaderLength定义的长度,out的对象就是自定义的错误消息,例:消息头的数组长度为零
现在有两个short,消息长度,和消息的code号。返回的是一个IPacketHeader对象,和SocketHandler的messageReceived方法相同,解析出消息的长度和消息code
IPacketHeader对象有两个属性必须读取,Id是对应的协议的消息号。PacketLength是消息包的长度
1.1.3源码:内部拿到的消息头IPacketHeader给ReceiveState设置读取的流长度,此长度仅为消息的长度。否则不会走帮助类的解析消息的方法。
然后重置消息头。通过方法DeserializePacket开始解析消息包内容PacketBase
1.1.4重写帮助类的方法DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData)方法,
通过上一步在DeserializePacketHeader的方法中解析出的消息头IPacketHeader的长度PacketLength和消息号Id,source的长度就是消息头IPacketHeader的长度PacketLength
从source中读取PakcetLength长度的byte[],从byte[]中反解出一个从服务器返回给客户端的消息 继承自LinkReadAndWritePacket的对象
PacketBase对象必须重写process方法,读取服务器返回的属性值,读完之后直接派发事件给主线程。需要的地方去监听消息号
按照现在的写法,下一步骤以弃用

弃用:NetworkChannel.RegisterHandler(IPacketHandler handler)会注册一个消息监听对象。key = handler.Id   value = handler.handle 通过pakcetBase的消息号判断当前消息的监听者。然后在监听者里做消息的执行
弃用原因:需要手动多写一个类,麻烦。

弃用:消息拿到后,会通过EventPool派发当前的网络消息包,源码中,是用字典m_EventHandlers存储消息号。派发事件,把当前的网络消息包添加到队列中(线程安全的),在消息派发的时候,是交给主线程操作的(线程安全)
在Update(float elapseSeconds, float realElapseSeconds)中检查队列的长度,lock锁定队列,从队列中拿到一个消息,从字典m_EventHandlers中获取监听者,执行监听者的逻辑

备注:消息的解析是在子线程中处理,消息全部解析完成之后,才会交给主线程,在对应的handle中处理。
消息的派发是在SC协议中派发,派发的唯一ID是在PacketIdEnum枚举中定义,需要数据的地方,监听PacketIdEnum中对应的消息,例:SCTest
1.2定义消息包和消息处理中心,做消息的传输。
1.2.1客户端发给服务器的消息,要继承LinkWriteOnlyPacket,在构造方法中按照约定顺序写入每个属性值,GameMain/Scripts/Network/Packet/CSTest
1.2.2服务器返回给客户端的消息,要继承LinkReadAndWritePacket,在process中读取约定的属性值,完成后使用GameEntry.Event.Fire派发事件(事件)。例:GameMain/Scripts/Network/Packet/SCTest
弃用:1.2.3消息的处理器,要继承PakcetHandlerBase,在Handle方法中,将数据转换成对应的SC数据,执行对外的操作,具体是交给管理器,还是直接广播本消息,看后期安排。例:GameMain/Scripts/Network/PacketHandler/SCPakcetHandler
1.3INetworkChannel.HeartBeatInterval设置心跳的发送间隔。设置为零的时候,为不发送心跳包
1.4封装networkmanager,提供给其他工作者接口。更方便使用
1.3.1客户端的主线程是不会阻塞的,在内部使用的是BeginConnect
1.5Socket的消息是接收到ReceiveState的Stream内存流中。默认长度时1024*8

备注:单个网络频道和多个网络频道在原理上是没有任何区别的,多个网络频道的好处是当出现多个服务器(聊天在A服务器,战斗在B服务器,好友在C服务器)的时候使用

每个数据层对象都有一个EventPool。通过EventPool进行数据的传输



GetNetworkChannel(stirng name)获取一个网络频道的对象


 
DestroyNetworkChannel(string name)释放当前的网络频道
 

你可能感兴趣的:(Unity)