您的位置  > 互联网

棋牌游戏服务器端总架构分为三层:,Core

研究了它的服务器框架后,我发现它的网络部分确实是比较优化的。 它主要使用提供的IO完成端口来实现其网络组件。 虽然这个服务器参考了它的设计,但是还是有很大的不同,因为这个服务器框架主要是在Linux系统上使用的,而棋牌则是基于平台的,并且非常依赖SDK。 该架构延续了棋牌在网络组件方面所做的努力。 本游戏和卡牌游戏的服务器也采用异步IO作为网络的工作方式。 更彻底的是它的数据库还采用了异步架构。 boost::asio 提供了一个异步框架,所以在它的几个核心组件中都可以看到 boost::asio 的影子: 、 、 。

,图1是整体架构图。 从图中我们看到服务器的整体架构分为三层:Core和. Core层以实现为基础,使用Core层提供的服务,监听Core层的异步事件(等)。

图1 棋牌游戏服务器总体架构

主要由4个库组成,其中boost::是跨平台线程库,boost::asio是跨平台异步IO库,用于序列化服务器和客户端协议,libpq是由一个开源数据库。 客户端官方接口支持异步数据库操作。

Core主要由4个组件组成,它们是建立在. 向应用层提供网络、数据库和定时器功能。 主要由Core本身内部使用。 提供定时器功能来管理来自客户端的连接。 并提供基本的数据库访问功能。

基于Core实现的服务器有四种类型。 它们管理游戏信息,提供登录和处理游戏逻辑功能。 以下是用户与这些服务器交互的经典流程:

1)客户端发送用户名和密码进行登录,登录验证成功后,将游戏列表返回给客户端。

2)当玩家选择特定游戏进入房间时,客户端发送请求,将房间信息返回给客户端显示

3) 玩家选择一张桌子坐下,游戏开始。 客户端将游戏动作发送到相应的服务器,解析操作并转发给游戏逻辑模块处理,并将处理结果返回给客户端。

这些服务器之间的关系是:

1)维护游戏列表信息和房间信息;

2)定期检索游戏列表信息和房间信息;

3)开始时注册,关闭时退出,并在玩家进入房间时通知并更新在线人数。 同时,游戏列表和房间信息也如期更新。

1 个故事

boost::asio是一个异步IO库,提供了通用的异步框架和基本的异步接口。 它的主要功能是响应程序的异步IO请求。 操作完成后,会被添加到一个完成队列中,完成队列上还有一些工作线程在等待。 这些工作线程从完成队列中取出已完成的操作,并调用上层应用程序提供的完成函数——。 asio库通过学习直接基于I/O端口的实现模式来完成这些任务。 在类Unix系统中,它们是根据epool等函数使用模式来模拟的。

libpq是一个开源数据库提供的客户端接口库。 我在这里选择它,一方面是因为它的跨平台性、稳定性和高性能,另一方面是因为我对这个数据库比较熟悉。 Libpq还提供了数据库连接、查询、更新等的异步实现,可以与boost::asio结合,提供统一的异步操作接口。

boost::库是一个用C++实现的跨平台线程库。 在C++11中,它已经被包含在标准库中。 这里主要使用这个库来实现一个线程池作为boost::asio的工作线程。 主要由Core层维护。 在代码的其他地方,线程不是直接启动的。 然而,在异步操作的完成函数中,需要对这些共享数据进行锁定和保护。

该库是一个为序列化对象而发布的开源高性能库。 支持多种语言,比如C++、Java、flash等,同时封装了字节序等琐碎的东西,方便上层应用。

2 核心层

核心层由 4 个组件组成: 、 、 。 以下是关于它们的基本描述。

它由 Core 内部使用。 它封装了 boost::asio 的功能并将其提供给其他几种用途。 从名字就可以看出,它的主要功能就是给其他几个提供异步调度。 这是通过boost::asio提供的函数实现的,但是是作为工作线程提供给boost::asio的。

有一个连接池来管理来自客户端的连接。 在内部,通过应用层注册的读写完成消息和通知被传输到应用层。 其相互作用包括:

1)调用注册接收网络读写完成消息;

2)调用发送数据;

3)recv完成后Core调用注册。

提供了定时器功能,层可以直接使用它来创建定时器和取消定时器。 当设定的时间到达时,创建定时器时指定的回调函数将被调用。

封装libpq,提供数据库的基本操作。 主要管理数据库连接,执行查询操作,执行存储过程等,其实现中有一个连接池。 与操作一样,它提供的数据库操作也是异步执行的,因此需要实现该层来监控操作结果。

3

以前的,无论是否核心,都已经死了。 仅添加逻辑。 他们是棋牌服务器的主要玩家。下面是他们更详细的信息

3.1

图2 与外界交互图

它不直接与玩家互动。 其主要功能是管理游戏列表和房间信息,包括:

1.游戏类型信息:桌游、休闲游戏、电子游戏等。

2、游戏类型:例如卡牌游戏类别下有:德州扑克、斗地主、升级等。

3、站点信息:因为这个服务器架构完全支持分发,所以站点信息也被保存。

4、房间信息:维护当前有哪些房间以及当前房间在线人数。

有关游戏列表的信息在启动时从该数据库加载,其房间信息来自于在启动时注册自己,在关闭时从数据库注销。 同时,当玩家进入房间时,也会被要求更新在线人数。

游戏列表和房间信息也应根据他们的要求返回给他们。

3.2

图3 与外界交互图

提供注册新游戏玩家和处理玩家登录请求的服务。

要求和交互包括:

1. 注册时输入已注册玩家的信息。

2. 玩家登录时,通过数据库查看玩家信息。

会定期发送更新游戏列表和房间信息的请求,因为这些信息不断变化,需要在玩家登录时返回给玩家。

3.3

图4 与外界交互图

有时,玩家可能会对游戏过程产生疑问,或者想回顾整个游戏过程。 这就需要服务器将游戏过程以Log的形式存储起来,供玩家查看。 用于响应玩家的验证请求,然后将整个游戏过程返回给客户端,客户端以视频的形式展示给玩家。

当玩家请求查看时,客户端会将游戏和玩家信息ID发送到服务器,服务器会根据游戏ID信息检索日志信息并返回给玩家。 游戏的过程可以用结构化语言来描述。 它本来就直接支持Json,也就是说Log可以以JSON的形式存储在数据库中。 但由于可能存在字节顺序问题,Log信息也必须序列化。 然后将其保存到数据库中。 从数据库读取日志后,直接返回给客户端进行反序列化,无需反序列化。

3.4

可能是最重要的类别,它将与游戏模块相结合。 它管理游戏中的房间,处理玩家进入房间、在桌子上寻找座位的请求,并将游戏相关消息转发给游戏模块进行处理。 不仅不同的游戏会有不同的,甚至同一个游戏也可能有多个。 例如德州扑克,可能有VIP房间、普通房间等,同一类型的房间还可能有Room1、Room2等,可以根据玩家数量按需设置。 图5给出了与外界交互的图。

图5 与外界交互图

启动时,必须先发送注册请求,关闭时,必须注销。 同时,还会定期通知和更新在线人数,并定期从互联网上检索最新的游戏列表和房间信息。

需要与玩家互动。 玩家进入房间、在桌子上找座位等请求都是由游戏操作来处理的。 例如加注、发牌等都会直接转发到游戏模块进行处理。

管理在线用户列表,该列表会在玩家进入和离开房间时更新。 有关此列表中的球员的详细信息是从数据库加载的。 当玩家玩游戏时,他的积分或者游戏币会因为输赢的关系而发生变化。 为了记录这些变化,他需要与游戏进行交互。

管理员可以发布消息、踢出玩家、警告玩家、设置玩家权限、设置房间属性等活动。

玩家还可以参与聊天(包括大厅中的公共和私人聊天)。

4 交互协议

客户端和服务器交互时,需要对传递的包进行序列化。 一个请求由一个或多个请求包/响应包组成。 每个请求包和响应包都有以下基本结构:

图6 服务器与客户端通信结构

表示请求的类型,例如游戏请求、房间管理请求等。

指具体请求,例如加注、踢掉玩家等。

表示pData字段的长度

pData 可以是任何消息。 如果是结构体,就需要序列化。

5个数据库

主要有三个: 、 、 。

:主要存储游戏列表信息。 这些信息包括 - 游戏类别列表、游戏类型列表和站点信息。

:主要存储与玩家相关的全局信息,包括玩家ID号、账号名、密码、二级密码、头像、经验值、登录次数、注册地址、上次登录地址等玩家属性信息。

:主要存储玩家游戏相关信息,如游戏积分、获胜、平局、逃脱、登录时间等。

从: