基于cobra_win实现上层游戏服务器
基于cobra_win实现游戏上层服务器
-----------关中刀客
----------- 2008 年 09 月 07 日
cobra_win是基于windows操作系统,使用IOCP技术,开发的一套网络底层通讯库。该库现在已经拥有一套完整可配置的内存管理容器,并且拥有强大的日志管理系统,线程类,仿linux内核实现的定时器管理器,以及IOCP相关的各种事件处理。cobra_win可为IM通讯软件,游戏服务器等提供强大的底层网络通讯库支持。
cobra_win采用XML语言作为配置文件,并使用著名的开源库tinyxml来对其进行解析,使用者在使用cobra_win进行开发的时候,只需要仅仅根据自己开发的项目设置相关的参数即可,无需改动cobra_win内部数据和模块。对于多线程环境中,为了保证关键数据区域的串行化操作,通常都是采用线程锁的方式,对于cobra_win的诸多内存管理器,使用者在使用时,可以根据自己的开发需要,定制是否为线程安全的内存容器,这样子对于容器的串行化操作,该容器内部会自动的进行加锁解锁,而不必在外层频繁的调用,极大地减轻了问题的产生频率。一个强大的日志管理系统,是一个项目成败的关键,对于我们的服务器程序来说,需要大量记录日志来记录各个阶段的关键信息,cobra_win的日志管理器,仿照java的log4cxx日志开源库,并进行了相关的精简,实现了可配置,分等级的日志管理器,并且考虑到效率的问题,cobra_win内部使用单独的线程来进行日志的纪录,在多核平台上,极大地提高了效率。考虑到一般网络游戏服务器的定时器定位在毫秒级别,我们吸收了linux源代码中定时器的实现机制,cobra_win实现了“双级缓冲,一级定长数组缓冲,二级双向链表缓冲”的策略,实现了对于毫秒级别的定时器管理机制,。
对于在使用IOCP开发网络服务器时出现的诸多问题,cobra_win都进行了合理的解决。首先,对于“死连接”问题,cobra_win在底层中,使用单独的线程来定时轮训所有连接,察看其连接的状态,如在规定的时间内没有进行数据收发,则超时并强制的关闭。在此,对于“IOCP发送大量数据导致没有可用缓冲区”的问题,在我们的cobra_win设置中,为了避免这个问题,我们使用集中缓冲发送策略,将我们需要发送的所有数据,先存储到固定的地方,然后根据定时器来控制发送的时间。对于服务器程序来说,我们经常会面临不定长的数据包,所以cobra_win底层实现了压包器EPacket和解包器DPacket来进行我们不定长数据的合并和拆分,极大地减轻了逻辑层面的设计复杂度。cobra_win已经将IOCP将要产生的各种事件单独的拆分出来,开发者只需要简单的继承自我们的IIOThread纯虚基类,然后实现相关完成事件的处理即可,不需要考虑底层的诸多实现细节,有利于节省开发时间,缩短开发周期,提高开发效率。对于异步多线程的使用,我们往往采用之间缓冲队列的方式,将底层IO多线程受到的数据,发送给上层逻辑线程的进行处理,但是,如果底层IO多线程的收包速度远远超过我们的逻辑线程处理能力的话,就会导致中间缓冲队列“爆炸”的情形,对于这个问题,cobra_win在设计的时候,采用“双缓冲安全队列”的方式,合理高效的避免了此种问题,使得服务器程序按照“流水线”的方式有效进行。
如何使用cobra_win开发上层服务器。本文将使用cobra_win,来实现一个完成的网络游戏登陆服务器框架。
首先,我们实现登陆服务器的服务器管理器类:
/*
* Copyright(c)2008
*
* 文件名称: ServerMgr
* 文件标识:
* 摘 要 : 登陆服务器管理器
*
* 当前版本: cobra_login_server 0.03
* 作 者 : 关中刀客
* E-Mail : [email protected]
* Blog : http://guan-zhong-dao-ke.blog.163.com/
* 完成时间: 2008 年09 月08 日
*/
#include <include/common/Header.h>
#include <include/common/Singleton.h>
#include <include/server/IOCPAcceptor.h>
#include <include/server/IOCPConnector.h>
#include "DMsgList.h"
#include "HeartBeatMgr.h"
#include "IOSendMgr.h"
#include <vector>
using namespace cobra_win;
class ServerMgr : public Singleton<ServerMgr>
{
private:
bool m_bRun; // 登陆服务器当前运行的状态
IOCPAcceptor m_Acceptor; // 本地监听器
bool m_bAcceptorState; // 本地监听器状态
IOCPConnector m_MasterServerConnector; // 主控服务器连接器
bool m_bMasterServerState; // 主控服务器状态
LOGINSERVER_CONFIG_INFO m_LoginServerCfg; // 登陆服务器的配置文件信息
IOSendMgr m_IOSendMgr; // 集中数据缓冲发送管理器
HeartBeatMgr m_HeartBeatMgr; // 心跳管理器
DMsgList m_DMsgList; // 双重队列缓冲器
std::vector<SOCKET> m_SocketList; // 连接上来的客户端列表
};
对于我们的所有基于cobra_win的服务器来说,都需要建立一个相应的服务器管理器,里面包含诸多的元素,如上面的例子所示:首先,我们需要一个控制当前服务器状态的标志位m_bRun;然后就是本地监听器来负责接受所有的链接,下来就是必要的连接器,连接我们指定的IP地址和端口,还有一个必要的相应服务器专有配置文件,下来就是我们的“双重安全队列缓冲区”和“集中数据缓冲管理器”。这样子就构成了我们大体的服务器框架。详细的例子,我们参见我们的附件地址。
目前,我正在使用cobra_win来实现一整套的网络游戏服务器框架,在目前实现的诸多上层服务器,如登陆服务器,总控服务器,网关服务器,逻辑服务器,数据库服务器中,cobra_win的表现非常的优越,简单高效,不再去考虑诸多的底层问题,我们将精力全部的放在了上层逻辑的设计和实现上。
cobra_win在设计之初,奉承“简单,高效,实用”原则。同著名的ACE相比,cobra_win显得十分的短小精悍,由于ACE框架过于庞大,所以其对程序员的要求太过苛刻,并且ACE的庞大和过于完整导致其内部很多模块耦合性太高,不利于我们提炼出来单独使用,并且在使用ACE开发的过程中,一旦出现问题,程序员往往难以快速的定位出错的位置和原因,给我们的开发带来了诸多的不便。相比之下,cobra_win内部模块划分相对清晰简练,耦合性低,非常有利于拆分出来单独的使用,整体cobra_win对外接口简单明了,开发者可快速的上手并熟练使用,另外,由于cobra_win的简单清晰,短小精悍,也非常的有利于在此基础上进行更上层的扩展和开发。
关中刀客,游戏开发人员,目前专心致力于cobra系列模块的设计与开发,如果您对cobra系列模块感兴趣或者有更好的意见看法的话,您可以通过[email protected]或者访问http://guan-zhong-dao-ke.blog.163.com/与他联系。