服务器框架 https://blog.csdn.net/nie2314550441/article/details/105981967
一、游戏服介绍
负责用户游戏逻辑处理。一个游戏服是一个游戏房间,例如:掼蛋金币房间(初级场、中级场、高级场),好友房,比赛场分别对应一个游戏房间,后台配置决定房间游戏玩法。一个房间有多个桌子,桌子数量后台配置,同一个桌子上的玩家可以一起玩牌,一个桌子有多个椅子,椅子数据感觉玩法来定,斗地主椅子数量是3,竞技掼蛋椅子数是4个。
二、服务器启动流程
1、启动准备
- 初始化网络库
- 监听事件注册
2、开始启动
- 创建日志、定时器
- 创建网络服务
- 挂接逻辑事件(用户线程读取网络数据)
- 创建广场客户端(与广场服进行连接)
- 和广场服连接成功时候发生房间配置请求
- 广场服将游戏房间信息发生给游戏服
- 加载游戏逻辑
- 初始化机器人
- 创建DB服代理服务(连DB服并进行消息交互)
- 创建中心服代理服务(连中心服务器并进行消息交互)
- 创建对象工厂
- 初始化网络连接池
- 目录监听服务启动
- 加载插件
- 启动网络服务器监听
3、启动流程图
三、广场服与其他服务器交互
- DB服务器启动
- 中心服启动并和DB服务器连接
- 广场服启动并和DB服务器、中心服进行连接
- 游戏服启动并和广场服连接
- 广场服将游戏服房间配置信息发生给游戏服,游戏服和DB服务器、中心服进行连接
- 网关服启动并和中心服连接
- 网关服连接成功发送登录信息
- 中心服收到网关服登陆信息,1.将网关服信息广播给已经连接的服务器;2.将所有和中心服连接的服务器信息发生给新连接的网关服
- 客户端连接网关服
- 客户端通过网关服将消息转发给广场服(如果未连接、先进行连接在转发消息)
- 广场服通过网关服将消息转发给客户端
- 客户端通过网关服将消息转发给游戏服(如果未连接、先进行连接在转发消息)
- 游戏服通过网关服将消息转发给客户端
四、类图
可以将广场服划分为八个模块。
4.1 DB服客户端代理
用于和DB服消息交互,详情参考《中心服——4.2 DB服客户端代理》。玩家私有属性,活动数据等等数据都是通过DB服客户端代理和DB服进行交互。
4.2 中心服客户端代理
用于和中心服消息交互,详情参考《网关服——6.1 中心服客户端代理》。接收中服发送来的配置数据已经其他服务器之间消息交互。
4.3 网关服代理
用于和网关服之间消息交互,当有玩家需要通过网关服将消息转发给游戏服,网关服代理会创建一个连接对象CConectionBase用于和玩家进行交互,详情参考《广场服——网关服代理》。
4.3.1 消息响应
游戏服和广场服一样也是将收到的网关发来的消息转发给对应的插件处理,游戏服和广场服处理不一样的时,广场服是直接通过插件id,转发消息,也就是我们在添加插件的时候只需要定义好对应的插件id,不用去管消息转发。而游戏服在收到网关服消息的是时候单独对应了一套消息id,导致我们再给游戏服添加插件的时候需要额外处理一下网关消息发送来的消息并将其投给对应的模块,没有必要这有处理,直接用插件id进行转发就可以了。
通过插件id转发消息好处:
- 不需要额外处理消息转发
- 底层逻辑处理不需要对上层暴露
- 减少业务层开发难道
4.4 创建连接对象和网络状态机
和广场服流程一样参考《广场服——创建连接对象和网络状态机》
4.5 玩家创建
和广场服流程一样参考《广场服——玩家创建》,不同的是玩家数据不是从DB中获得,而是广场服发送给游戏服。
4.6 插件
和广场服中插件结构一样,广场服插件主要负责玩家在广场的活动或玩法逻辑处理,游戏服中插件主要负责游戏房间中的功能模块,例如,机器人插件负责管理机器人;比赛场场负责比赛逻辑处理;房间插件负责房间管理,房间插件是一个非常重要的模块后续会详细说明。
4.7 广场服客户端代理
游戏服通过广场服客户端代理和广场服进行通信。通信可以分为两个部分,一、游戏服起服,游戏服起服时会先和广场服进行连接,通过广场服发送来的房间信息,启动游戏服;二、传递玩家数据,当玩家进入游戏服广场服会将玩家一些信息发生给游戏服,游戏期间和广场服数据交互。
4.8 游戏模块
负责处理游戏牌桌逻辑处理和机器人玩牌逻辑处理
4.8.1 结构
根据房间配置构建相应的机器人玩牌逻辑和牌桌逻辑处理。
4.8.1 类
- CGameModule:游戏模板,对牌桌逻辑和机器人玩牌逻辑初始化和创建进行一层封装并提供游戏数据长度接口。例如,玩家自定义数据——不同游戏类型数据长度不一样根据游戏逻辑自行定义,桌子数据长度——根据游戏逻辑自行定义。
- CGameRobotSinkAgent:机器人代理,根据游戏配置创建对应的机器人处理对象。
- CGameSinkAgent:游戏逻辑代理,根据游戏配置创建对应的游戏处理对象。CGameSinkAgent有多个,一个桌子对应一个游戏逻辑代理对象,它负责一个桌子的牌局逻辑。
五、游戏房间
游戏房间属于房间插件模块,房间插件是整个游戏服中最重要的模块。一个房间包含多个桌子,桌子数量在房间配置中获取,一个桌子是一次牌局中最小单位,一个桌子包含多个椅子,一个椅子可以坐一个玩家。一个桌子绑定一个游戏逻辑,由于该配置有些逻辑处理。
可以将游戏房间划分为三个部分
5.1 游戏模块
对应4.8游戏模块,负责各个游戏和对应游戏机器人逻辑处理,一个桌子对应一个游戏逻辑。
5.2 房间插件
负责玩家进入/退出牌桌,通知游戏模块游戏开始等等和游戏房间相关的操作
5.3 媒介
游戏模块和房间是通过接口IGameConvenient进行交互,游戏模块通过IGameConvenient将消息发送给房间模块,房间接口通过桌子id获取游戏模块对象,进行消息交互。
5.4 创建过程
- 根据配置桌子数量创建桌子并记录每个桌子的便捷接口指针:IGameConvenient
- 通过全局对象获取游戏模板对象CGameModule,将IGameConvenient和桌子数量用于初始化游戏逻辑参数,创建和桌子数量相等的游戏逻辑对象,每一个游戏逻辑对象都保留一个IGameConvenient指针,用于游戏逻辑对象消息回调给桌子。桌子id和游戏逻辑对象id相同,桌子对象可以通过桌子id获取到对应的游戏逻辑对象。
5.5 总结
桌子负责玩家在桌子上的逻辑处理,游戏逻辑对象负责一个游戏玩法的逻辑处理,游戏逻辑对象依附于桌子,一个桌子可以根据房间配置不同,可以和不同的游戏逻辑对象进行广联,也就是桌子可以不变,桌子上的游戏可以根据配置不同,进行不同的游戏。这个过程将牌桌和牌桌上的游戏逻辑进行了很好的解耦。