干货丨Step By Step创建你自己的游戏服务器(五)一个聊天室的示例
发表于2016-08-04
干货丨Step By Step创建你自己的游戏服务器(五)一个聊天室的示例
截止上一篇,其实大致的想法方向都说完了,剩下一些实现的细节,具体的和游戏的内容有关,就不进行下去了。
我以一个完整的登录流程再加上最简单的交互--聊天为示例,做这一阶段的总结。这部分的代码,同样可以从GitHub上获取到,对应的客户端是Client项目。
在做客户端之前,先完善游戏服务器。
游戏服务器的对话接口都是Command,Command可以分为两个级别:Level1和Level2. (笑)Level1 是高级别,比如和网关的交互。Level2级别低,是游戏玩法交互。
大多数的通讯都是属于Level2,网关直接做转发就可以了。而Level1是需要做特殊处理的,比如进入游戏和退出游戏。
看之前的设计,所有的连接都在网关上,那时候的通讯交互都是交由ThreadPool来完成的,是异步的,但是到了游戏服务器,所有的报文汇聚到了一个消息队列中,排队经过解析、执行。就像是来自各处的涓涓细流汇聚到一起一样,这个队列的缓冲区也是很大的。在Gate那边,我们可以通过SessionID来找到对应的客户端会话(Session),可到了Game那边,就不知道谁是谁了。于是我加入一个NetHandle作为标识,NetHandle是个整型,绑定UID,UID可以是任意唯一字符串,长度不好控,所以使用一个整型来标识客户端。
GameServer看到NetHandle就知道是哪个UID了,GateServer看到NetHandle就知道是哪个Session了。
点对点的发送就这样,点对面的发送是需要优化的,因为发送的内容一样,所以只要在GameS通知GateS的时候在头上带上需要群发的NetHandles即可,大大减小了通讯量。如果什么NetHandle都没有那就是默认全服群发Broadcast。
还有在缺失NetHandle情况下的G2G通讯,比如玩家刚进游戏的时候,所以,进入和退出两个是Gate主动提出的特殊报文,经特殊的GameServer的Command处理。登录之后记入字典,在进行接下去的操作的时候,直接从字典从取出对应的Player对象,在Command.execute()里作为参数传递引用。在客户端主动断开连接或是服务器判定客户端协议错误有作弊嫌疑的时候Gate需要发送一个特殊的离开报文到GameServer。游戏服务器判断客户端有作弊嫌疑也要发送特殊报文给Gate处理,Gate接收之后断开Session的连接。
然后讲一下ProtoBuf,我在Tools/Helper/文件夹下放置了两个文件夹,分别是Protocols和Tools文件夹,在protocals文件夹下是proto文件,Tools文件夹下放置了用于转换proto文件到cs文件的工具。
我加上了Chat的报文,生成cs文件后复制到GameServer的Entity目录下。创建ChatCommand,每收到一个报文就全体群发。
客户端方面,另建了一个Client项目,用WebRequest访问loginServer获取token,用TcpClient访问gateServer。
你现在可以通过修改访问的loginServer的地址来试玩。我也建了一个公网的服务器,地址是123.56.119.97,端口是8080。测试用账号test2,密码123
如下图位置: