网络游戏一般采用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.合理的规划拆分数据库。