随着计算机网络的发展,特别是因特网的出现,数字娱乐和网络游戏产业得到了蓬勃的发展,异军突起的网络游戏成为中国网络产业中的先锋。而由于信息技
术的进步,计算机、手机以及不同的传媒终端等不断涌现,如何将这些众多不同的终端通过互联网进行互联互动成为一大技术难点,而这些难点的突破取决于网络游
戏服务器的开发。目前在各种服务器通信软件的设计和开发中,已经广泛地使用到软件设计模式。尤其在大型的服务器通信软件开发中常会采用模块化设计。当一个
庞大的服务器系统执行任务时,往往要通过其中不同的模块进行协作完成,在这种情况下各机间的数据通信会变得异常繁琐和复杂。另外不同操作系统通信机制的不
同也会影响通信软件的开发和效率,网络编程人员通常从底层进行开发,这大大增加了软件开发的难度和周期。针对以上存在的问题,ACE自适应通信构架给出了
良好的解决方案,ACE能够跨越多种操作系统平台,可进行通用的网络编程任务,并结合软件设计模式,避免了通信软件根据不同环境需要重新开发的弱点,减少
了软件开发的周期和资金,简化和强化了系统的设计实现。
1 ACE框架
ACE
自适应通信环境(ADAPTIVE
CommunicationEnvironment)是可以自由使用、开放源码的面向对象(OO)框架(Framework),在其中实现了许多用于并发
通信软件的核心模式。ACE提供了一组丰富的可复用C++Wrapper
Facade(包装外观)和框架组件,可跨越多种平台完成通用的通信软件任务,其中包括:事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通
信、共享内存管理、消息路由、分布式服务动态(重)配置、并发执行和同步等。ACE体系结构包括3个基本层次:操作系统适配层、C++包装层、框架组件
层。操作系统适配层直接驻留在用C写成的本地OS API之上,将ACE中的其他层与OS
API相关联的平台专有特性屏蔽开来。由于ACE操作适配层所提供的抽象,极大地增强了ACE的可移植性和可维护性。C++包装层通过提供类型安全的
C++接口简化通信应用程序的开发,各种应用可以有选择地继承、聚合或实例化其中的组件来使用这些包装。ACE还包括一个高级的网络编程框架,集成并增强
较低层次的C++包装层,该框架支持并发分布式服务动态配置。
大多数的网络化应用可以通过ACE这样的可移植中间件进行开发,因为ACE封装并加强了本地操作系统机制,通过其组件可以移除底层操作系统API的繁琐和易错性创建可重用的网络程序。
2 网络游戏服务器系统框架的设计
在设计网络服务器的过程中,如何保证服务器的安全和最大限度地支持更多的客户端连接是摆在开发者面前一个重要的问题。为了解决这2大问题,根据经验,在开发游戏服务器的过程中,采用如下的服务器架构可有效解决上述2个问题。
2.1 支持Gate的游戏服务器架构
在该架构下,Client和Gate Server相连,而不是直接和Game Server相连。Gate Server主要负责转发客户端和Game Server之间的数据包,Game Server负责处理游戏的所有逻辑。如图1所示。
采
用该架构,有如下几个优点:客户端通过Gate Setver和游戏服务器Game Servet相连,Game Server
IP对外不可见,这样Game Server更安全、更不易受攻击。一个Game Server同样也可以对应若干个Gate
Server,当某个Gate Server受攻击或停机后,其他的Gate Server仍然照常运行,和其他Gate
Server相连的客户端仍然可正常进行游戏;可支持更多的客户端连接。Gate Server把众多的客户端连接分散到多个Game
Server中去,而不是独自来承担,从而可支持更多的客户端连接;Gate Server可分担一部分安全管理工作,减轻Game
Server的压力。例如若某个客户端在一段时间内不发数据包,则把该客户端踢下线的工作可由Gate Server来完成。
2.2 软件功能模块划分
在
设计服务器框架时,有一个基本原则,即框架和通信底层的具体实现需要分离,通信底层的具体实现不影响框架代码的修改。因为通信底层的具体实现有很多方式,
不同操作系统平台的具体实现差别也很大。例如仅在Windows平台下就有基于Windows消息机制的、基于事件机制的、也有基于完成端口I/O模型的
实现等。采用框架与通信底层相分离的原则,也有利于利用一些成熟的开发框架,比如使用的ACE框架。这样,当采用一种新的通信技术实现通信底层时,则可以
不改变服务器框架,而只需要修改通信底层。在设计服务器时按照服务器框架与通信底层相分离的原则,将服务器框架设计为多个模块。并生成相应的动态链接库以
供调用。软件模块框架如图2所示。
在
软件模块划分中,通信底层由线程模块和通信模块组成,上层则由同步、联机管理和兴趣区管理等模块组成。其中同步模块是基于保守/乐观的同步算法构建的服务
器同步子系统,客户端方面则可以使用航位推测法减少服务器的发包频率。兴趣区管理模块用于相关性信息过滤,通过订购玩家感兴趣的范围,可以有效减低网络带
宽消耗和服务器负载。联机管理模块主要负责数据封包中的通信协议以及数据报的压缩和加密,在数据包中采用加密以增加服务器系统的安全性能,采用压缩以减少
网络带宽消耗。
3 服务器系统通信底层的实现
3.1 线程模块的实现
在
设计线程模块中使用ACE框架中的ACE_Task类和ACE_Message_Queue来实现主动对象模式,用于处理主动对象,实现多线程处理。传统
的对象是被动的代码段,对象中的代码是在对他发出方法调用的线程中执行的,当方法被调用时,调用线程将阻塞,直至调用结束。而主动对象却不一样。这些对象
具有自己的命令执行线程,主动对象的方法将在自己的执行线程中执行,不会阻塞调用方法。由于主动对象的方法调用不会阻塞,这样就提高了系统响应速度。
设计中主动对象继承ACE_Task,应用open进行初始化,并派生线程去循环判断方法队列中是否有方法对象,若队列不为空则将方法出队并执行。如图3所示。
在创建任务和主动对象时,从ACE_Task类派生子类,在子类派生之后,采取以下步骤:
(1)实现服务初始化和终止方法:open()方法应该包含所有专属于任务的初始化代码;close()方法则包含相应的终止方法。
(2)
调用启用(Activation)方法:在主动对象实例化后,必须通过调用activate()启用他。在主动对象中创建的线程的数目,以及其他一些参
数,需传递给activate()方法,activate()方法会使sve()方法成为所有他生成的线程的启动点。
(3)实现服务专有的处理方法;在主动对象被启用后,各个新线程在svc()方法中启动。
并发策略实现的程序流程如图4所示:
3.2 通信模块的实现
3.2.1 反应器ACE Reactor和前摄器ACE Proactor
ACE Reactor(反应器)和Proactor(前摄器)是可扩展的面向对象多路分离器,他们分派应用专有的处理器,以响应多种类型的基于I/O、定时器、信号和同步的事件。
ACE_Reactor
反应器应用于同步I/O操作,实现了事件的多路分离与分派,能够处理多个来源的I/O。使用反应器框架,需要执行3个步骤:从
ACE_Event_Handler派生一个和多个事件处理器类,并定义相应的事件处理行为;向ACE_Reactor类登记应用的事件处理对象;运行
ACE_Reactor事件循环,事件发生时回调事件处理器中的事件处理函数。
ACE_Proactor应用
于异步I/O操作,他与反应器不同的是首先等待事件的完成,然后回调完成后的事件处理。当初始化I/O读写后把读写交给系统完成,等待事件完成后前摄器会
将执行I/O结果返回给对象,并且回调完成后的事件处理。前摄式模型允许单个应用线程同时发起多个请求。这一设计允许单线程化应用并发的执行多个I/O操
作,并且不会带来与传统的多线程化机制相关联的开销或设计复杂性。这样做大大减少了I/O处理时间。
3.2.2 利用前摄器实现高效异步I/O数据通信
在实现通信模块中使用的前摄器模式主要参与者有前摄发起器、完成处理器、异步操作、异步操作处理器、完成分派器。其结构如图5所示:
其中,前摄发起器(服务器应用的主线程)是应用中任何发起异步操作的实体。他将完成处理器和完成分派器登记到异步操作处理器。完成处理器接口用于异步操作
完成通知,异步操作则是被用于代表应用执行请求。当异步操作完成时,异步操作处理器将应用通知委托给完成分配器。异步操作是由异步操作处理器来运行直至完
成的,该组件通常由操作系统实现。完成分派器负责在异步操作完成时回调应用的完成处理器。当异步操作处理器完成异步发起的操作时,完成分配器代表应用执行
应用回调。该机制的实现交互图如图6所示:
3.2.3 通信连接的建立
在
具体通信模块中,所用到的ACE主要类有异步连接类、服务处理类、异步操作类和处理结果类。建立连接的过程为:创建异步主动连接和被动连接子类,在进行异
步连接时,创建新的服务处理类,并将该服务类传递给异步连接类,这样,数据的传输就交给服务类去执行。实现服务处理子类中提供的挂钩方法,并通过创建
ACE_Sock_Stream和异步读写流类来进行异步通信。在异步读写流初始化时将其注册到已创建的proactor中,并保存异步读写流类的句柄。
最后数据传送的结果和状态交给处理结果类来处理。异步通信的初始化:
(1)分别创建异步主动连接类的派生类和被动连接类的派生类
class TCommandChannelConnectorAcelmpl:public ACE_Asynch_Connector<TCommandChannelAcelmpl>
class TCommandChannelAcceptorAcelmpI:public ACE_Asynch_Acceptor<TCommandChannelAceImpl>
(2)创建主动连接类对象connector和被动连接类对象acceptor;
(3)对于主动连接,调用connector.open(…),并将其注册到Proactor,由框架自动创建异步通信服务类,并且自动检测连接建立状态;
(4)对于被动连接,调用acceptor.open(…),并将其注册到Proactor,由框架自动创建异步通信服务类,并且自动检测连接建立状态,处于等待侦听状态;
整个异步通信机制实现的流程如图7所示:
3.2.4 ACE_Proactor完成多路分离
ACE_Proactor类负责驱动前摄器框架的完成处理。要让异步I/O完成事件处理得以发生,还需要运行前摄器的事件循环,其流程图如图8所示。
4 结 语
本
文设计了一种适用于开发网络游戏的服务器端架构,并应用ACE框架组件和面向对象的设计模式完成服务器底层通信的开发。ACE作为一种免费开源的中间件,
富含网络与系统编程的实用设计模式,具有跨平台等优越特性,能够适合任何通信软件的开发。尤其对于网络游戏服务器开发者而言,ACE无疑是一种值得借鉴的
通信框架,具有良好的应用前景。