天龙客户端的网络模块

  网络在游戏引擎结构中处于底层,无论什么联网游戏都绕不开。网络层要实现的功能包括登录认证,连接服务器,收发消息包,断线检测,重连服务器等等。我原来的方案是封装Socket,开一个网络消息接收线程,用Socket的recdata接口,再加上一个心跳机制来检测是否掉线,现在是够用了,但经常出现莫名其妙的掉线,很是不理解。

  网络消息的发送,原来用一般就是一个固定的消息头,头结构里有消息号,消息体就自定义了,每个消息并没有直接封装,也就是说要发的消息并不是个对象。天龙定义了一个抽象基类代表所有要发送出去的消息,PacketDistributed,每一个要发送的消息都是这个对象。此对象可根据消息号创建出派生出来的消息封装体,能调用网络接口把本体数据发送出去,支持写入发送缓冲区。每个具体的派生对象负责自己的实现。

  从网络收到消息后怎么走的流程呢。首要涉及的就是分消息号和对对应消息号的解析,这个功能的设计相信所有网络游戏都会碰到。之前我的做法是,每个消息号对应一个Handler,谁用这个消息,谁负责写Handler,但是很遗憾,同事们对此的执行能力不行,写的乱七八糟。天龙是集中维护了一个PacketFactoryManager,其中有个消息号(PacketFactory)和消息处理函数(IPacket)的对应表,只要加消息,就需要有对应的处理器。PacketFactory代表一个消息,核心数据是消息号;IPacket代表对一个消息的处理,核心是一个Execute虚函数;如果重新设计的话,也可以这么干,每个消息都对应一个处理器,作为规范定下去。

  关于网络字节流的处理。之前端游等可能很普遍的方法是二进制字节流,然后逐个核对消息结构的字节,这种方法实际上容错能力极低,只要有一个字节格式不正确,这条消息就算挂了,甚至整个游戏的消息缓冲就都坏掉了。现在手游用的很多的应该是Google Protocol buffer,在网络字节的优化上一定有冗余,但在易用性上会好很多。谷歌官方对protobuffer有三种实现,分别是C++,Java,Python,唯独没有C#,也许谷歌内部是排斥微软那些东西的,开发的时候能用Java就不用C#了。 现在看起来有几种C#的实现,天龙用的应该是protobuf-csharp-sport,另外一个是protobuf-net。这两种大家普遍认可前一种,为什么呢,他的实现更像谷歌提供的那三种语言实现的风格,基本上他的实现是在Java基础上写的,因此适宜于我这种C#语言写客户端,与Java写的服务器之间的通信,如果两头都是C#,那么后者更合适。这也不是本人的经验,可以看看大牛们是怎么说的:http://stackoverflow.com/questions/2522376/how-to-choose-between-protobuf-csharp-port-and-protobuf-net

  天龙的网络管理器NetManager,封装了连接服务器,发送/处理消息包,重连服务器,断开服务器,网络线程的创建与销毁,连接/断开连接的回调等功能,但实际的实现放在NetWorkLogic里,提供了用户登录接口(以及完成回调),用户登出接口,选择角色接口(以及完成回调)等。网络连接掉了之后,ConnectLost函数里要进入选服界面(异步过程),等进到选服界面后网络清理,UI清理,然后场景相机active false。也有连接监听代理和连接丢失代理这些常用的功能。和其他项目相似,类里维护了一个连接状态,分别是INVALID,CONNECTING,CONNECTED,DISCONNECTED,分别对应无效,连接中,已经连接上,未连接。我的项目里连接中,无效这些状态没什么大的用处。我考虑的话,最主要弄清楚的是网络分层结构。

下一步准备看看AssetBundle的管理。

 

posted @ 2015-01-29 19:22  DesignYourDream  阅读(426)  评论(0编辑  收藏  举报