网络游戏一般采用C/S结构,客户端负责绘制游戏世界的实时画面,服务器端则负责响应所有客户端的连接请求和游戏逻辑处理,并控制所有客户端的画面绘制,客户端与服务器通过网络数据包交互完成每一步游戏逻辑。
网关服务器方式,主要职责是将客户端通信和游戏服务器隔离。
网关服务器只负责解析数据包、加解密、超时处理、过滤错误包,客户端只需建立和网关服务器的连接即可进入游戏,无需与游戏服务器直接连接。
网关服务器分为LoginGate(登录网关服务器)、GameGate(游戏网关服务器)。
1.LoginGate主要负责在玩家登录时维护客户端与LoginServer之间的网络连接与通讯,对
LoginServer和客户端的通信数据进行加密、校验。
2.LoginServer主要功能验证玩家账号是否合法,并生成一个登录凭证SESSIONKEY。
3.GameGate主要负责客户端与GameServer之间网络连接和通讯,对客户端请求和发送数据做简单分析。
4.GameServer主要负责游戏逻辑处理,包括战斗系统、任务系统、角色系统、地图系统等。
5.DBServer主要负责游戏数据缓存,包括玩家游戏属性数据,降低数据库压力。
6.Mserver负责一组服务器中对多台GameServer之间数据转发和广播。
7.Mysql负责数据持久化存储。
服务端事件系统
什么是事件系统
事件系统是整个WebGame系统里一个核心的组成部分,它控制着游戏的进程,使游戏能够及时执行到期命令。
事件是指游戏里玩家的某个活动指令,它可以分为瞬时活动和非瞬时活动。
瞬时活动顾名思义就是在玩家发出指令的瞬间就能完成的活动。
玩家从NPC里购买一瓶药水,在玩家发出这个指令后,玩家的金钱减少,药水增加1瓶,这一切都在玩家发出指令后瞬间完成。
而非瞬时活动则是在玩家发出某个指令后一段时间才会被执行。
例如RPG游戏里玩家鼠标点击地图上某个怪物进行。这个过程就是一个非瞬时过程,它有了一个战斗的过程,这个过程需要消耗一定的时间。
在WebGame里,玩家的很多操作可以看作时候瞬时事件和非瞬时事件的结合。
例如在策略游戏里升级建筑物,瞬时事件是村庄资源减少,非瞬时事件是建筑物建设,非瞬时事件的结果是建筑物等级上升。
比如策略游戏中的军队战争,瞬时事件是当前村庄的士兵减少,非瞬时事件是减少的士兵移动到需要的村庄,结果是,两个村庄开打了。
数据库存储方式与内存存储方式对比:
游戏中的事件队列会比较多,体现在数量和类型上。各种各样的事件队列。
SLG游戏中:
1.城池建造建筑。
2.城池间战争。
3.城池造兵。
4.研究科技。
RPG游戏中:
1.战斗打怪或PK。
2.连续打怪挂机。
3.修炼挂机。
4.技能修炼。
LINUX消息队列存储的优势在于降低了PHP进程对数据库查询压力,缺点是服务器宕机,内存中存储的消息事件队列将会丢失,RPG打怪事件队列丢失影响不大,只是当前打的这个怪物无效,但是其他类型的事件队列丢失话有可能影响巨大,还有查询到期事件的效率问题。
客户端玩家发起战斗事件指令,服务端PHP接收到该事件,进行战斗合法性验证后将该事件即相关运算数据存储到LINUX消息队列中,PHP战斗进程监听LINUX消息队列。
如果发现消息队列中有战斗事件:
1.PHP运算进程进行运算。
2.PHP运算进程在运算完之后将运算结果写入玩家战斗结果DB内存表中存储,并将战报借助IM推送到客户端进行播放。(注:战斗结果是存DB中还是存入LINUX消息队列或MEMCACHE内存中?)
3.PHP战斗结束进程监听数据库中玩家战斗结果表,战斗结束时间到,则删除该条数据,
并处理战斗奖励。
4.避免玩家重复发起战斗事件,可以在服务端通过玩家ID验证是否有正在战斗的战斗队列。(注:是否需要做服务端战斗状态验证?怎么做?查询检索?)
综上分析,服务端战斗相关进程会有两个以上,PHP监听战斗事件并运算进程,PHP监听战斗结束进程。 PHP处理战斗运算进程可以扩展出战斗运算分布式服务器。
对于任何项目,一个好的数据库设计极其重要,对于WEBGAME来说就更是重中之重了。一个好的数据库设计相当于一付好的骨架和脉络,当你的骨架搭建好,脉络理顺后,再进行游戏功能代码的时候将会非常顺畅。
怎么样才能设计好一款WEBGAME的数据库呢?
在设计前因做好如下准备:
1.对于游戏业务逻辑要相当清晰。
2.多和游戏策划人员进行沟通,充分了解游戏功能需求。
3.发现游戏逻辑部分有矛盾时及时向策划人员反馈、调整。
4.对于游戏功能先按模块进行划分,然后再细化到每张表结构。
5.对于游戏逻辑复杂的功能点需要反复推敲。
开始设计数据库的时候因注意:
1.表名、字段名规范化,按游戏功能模块划分逻辑相近的表放在一起。
2.合理的区分游戏配置数据表和玩家数据表。
3.游戏配置数据表和游戏玩家数据表在表名上区分开,或则分库。
4.合理权衡表结构的逻辑关系、性能优、易理解、易扩展。
5.表字段类型长度设置合适,能用int就不要用varchar,能用mediumint就不要用int。
6.合理使用数据库表的纵切与横切来降低表压力。
7.合理规划表结构,常用字段和非常用字段,尽量在设计上避免关联查询。
8.一定要用INNODB事务表,游戏数据表中处处都是事务关联数据。
9.合理使用JSON格式进行数据存储。
10.数据冗余和性能权衡是个问题,比如用户昵称、职业等字段。
11.设计好表索引字段、用好联合索引。
12.在合适的功能上用好数据库内存表。
13.通过SQL来验证数据是否存在时一定要用COUNT(*)。
14.主从数据库用在游戏中会有数据延迟问题,不够实时。
15.合理的规划拆分数据库。