一、网关服介绍
客户端与服务器之间消息交互通过网关服进行转发,客户端与网关服通过TCP进行连接,网关服将客户端消息发送对应服务器(登陆服、广场服、游戏服),对应服务器收到消息之后进行处理,处理完再通过网关服将消息发送给客户端。网关服也可以的对消息进行校验,防止恶意攻击。这里只考虑客户端与游戏服务器之间消息交互,客户端与CDN、Web服务器之后通信不考虑。
二、服务器启动流程
1、启动准备
- 初始化网络库
- 监听事件注册
2、开始启动
- 创建日志、定时器
- 创建网络监听服务并启动监听
- 挂接逻辑事件(用户线程读取网络数据 )
- 创建中心服代理服务(连中心服务器并进行消息交互)
- 创建服务器连接代理管理器
- 创建守护中心(与守护中心服连接,用于服务器拉起)
3、启动流程图
4、补充说明
1、2.3中【挂接逻辑事件】:通讯层的各种事件(网络连接、断开、接收、发送)都是在通讯线程触发的,而用户希望收到的通讯事件必须在用户线程,这样上层代码就不需要额外处理线程同步的操作,所以在用户线程的主循环里,需要持续调用DispatchNetworkEvents函数来驱动通讯事件的派发,类似在主循环收取窗口消息一样。
2、2.4中【创建中心服代理服务】:网关服启动时会和中心服进行连接,通过中心服代理服务与中心服进行消息交互。
3、2.5中【创建服务器连接代理管理器】用于管理网关服发起连接的服务器:登陆服、广场服、游戏服。
4、2.6中【创建守护中心】通过守护中心客户端与守护中心服务器进行连接,用于服务器宕机拉起。
三、客户端与网关服消息交互
- 网关服成功启动
- 客户端通过TCP连接网关服
- 网关服网络层收到连接之后,将连接消息发送给GatewayServerCenter::OnAccept
- 网关服应用层收到连接之后,判断连接IP是否被限制,若限制断开该连接,未限制则会new CClientProxy,并与当前连接对象进行绑定。新创建的客户端代理对象会在其构造函数中将自己添加到GatewayServerCenter用户对象记录中进行管理。
- 客户端发给网关服的消息会通过网络层转发给与之对应的客户端代理对象——CClientProxy。
- 网关服发送给客户端的消息通过客户端代理对象——CClientProxy,发送给客户端。
一个客户端与网关服通信流程如下图:
四、网关服消息转发
- 客户端和网关服建立连接
- 网关服通过CClientProxy与对应的客户端进行消息交互
- 当客户端需要将消息发送给登陆服(游戏服、广场服流程一样),网关服的客户端代理服务收到客户端消息之后,对消息头进行解析,此时消息是需要发送到游戏服,网关服查找登陆服信息并随机选中其中一个,网关服将消息发送给该登陆服,如果网关服和选中的登录服还未连接线连接再发送。需要说明:登陆服通过服务器类型进行查找,登陆服可以有多个;广场服通过服务器类型进行查找,广场服只有一个;游戏服通过服务器id进行查找,玩家只能进某个具体的游戏服。
- 登陆服通过网关服将消息转发给客户端
网关转发消息流程如下
五、网关服与其他服务器消息交互
- 网关服开启前会先和中心服务器进行连接
- 别的服务器(登陆服、广场服、游戏服)启动前会与中心服进行连接,中心服和其他服务器连 接成功之后,会将其他服务器基本信息发给网关服。当有服务器与中心服连接成功之后,中心服会将新连接成功的服务器信息广播给所以与中心服连接的服务器。
- 网关服收到中心服发送过来的其他服务器信息,并记录改信息。
- 客户端发送消息给网关服务器,网关服需要将消息转发给对应服务器,当需要转发的服务器未与网关服进行连接,网关服会先和对应服务器进行连接(前提是网关服收到了中心服发送过来的该服务器信息),再将消息转发给对应服务器。
下图是网关服转发客户端消息到登录服流程图
六、类图
可以将网关服划分为三个模块。
6.1 中心服客户端代理
6.1.1 功能
- 与中心服进行连接
- 连接成功获取本地服务器信息并发送给中心服。
- 接收并记录中心服发送来其他服务器信息。(中心服会将已经连接成功的所有服务器信息发生给新连接的服务器并将新连接的服务器信息广播给所有已经连接的服务器。)
- 接收中心服发送来的网站后台配置信息,并将接收的配置信息转发给调用中心服客户端代理对象即:网关服对象GatewayServerCenter。
6.1.2 设计原则
中心服客户端代理,符合开闭原则,对修改关闭,对扩展开放。中心服代理客户端在多个服务器中都需要用到(网关服、登录服、广场服、游戏服、Web服),获取服务器信息和接收返回消息约定好接口,各个调用中心服客户端代理的服务器各自处理需要的数据和逻辑,不需要对中心客户端代理进行修改。
6.1.2.3 接口
下图是需要用到的两个接口:
- ICenterSink:调用中心客户端代理对象需要继承的接口,用于中心服客户端代理返回消息
- ICenterClient:调用中心客户端代理对象获取数据接口。
6.2 服务器管理
6.2.1 功能
- 提供接口用于获取一个连接:登录服务器连接、广场服务器连接、游戏服务器连接
- 通过中心服代理客户端获取其他服务器信息,随机选择一个符合要求的服务器,返回它的连接对象,如果没有连接先进行连接再返回。
- 为每一个连接客户端创建一个代理接收和发送对象(ClientProxy)。
- 负责网关服和其他服务器之间消息交互
- 负责客户端和服务器之间消息转发
6.2.2 类
- CGatewayMgr:提供接口用于获取一个连接:登录服务器连接、广场服务器连接、游戏服务器连接。一个CGatewayMgr对应多个GatewayClient。
- GatewayClient:负责网关服与某一个服务器之间消息交互。一个GatewayClient对应多个ClientProxy。
- ClientProxy:一个玩家用于和某个服务器消息交互。
6.3 客户端代理
6.3.1 功能
- 负责客户端连接。
- 将客户端消息转发给服务器(登录服、广场服、游戏服)。
- 若未和服务器建立连接,先缓存客户端发送的消息,在和服务器成功连接建立之后将缓存中的消息发送给服务器。
- 将服务器消息转发给客户端。
6.3.2 类
CClientProxy:网关服每收到一个客户端连接会创建一个CClientProxy,CClientProxy负责接收该客户端消息并转发到对应服务器。CClientProxy中包含有三个ClientToServerProxy对象分别用于续传消息发送给登录服、广场服、游戏服。
ClientToServerProxy:用于续传消息发送给某个服务器(登录服、广场服、游戏服),当未和某个服务器进行连接先通过NewXXXServer()获取一个连接对象ClientProxy,并发送登录消息,将客户端IP、端口发送给服务器,服务器收到消息之后会返回登录成功消息给网关服,当收到登录返回消息之后表示创建建立了连接。续传消息和发送并接收登录消息是一个异步过程,需要在未收到登录返回消息之前将发送的消息进行缓存,并在收到登录消息之后再将缓存中的消息发送给服务器。