您的位置:首页 > 运维架构 > 网站架构

游戏服务器架构分析

2014-11-30 00:36 357 查看

记录下我们游戏服务器的架构

游戏服务器逻辑架构图




我自己设计的游戏逻辑架构图




游戏服务器程序框架图




程序入口代码

// 读取此服务器相关配置

Log.Notice("Config", "Checking config file: %", config_file);

if(Config.MainConfig.SetSource(config_file, true))

{

Log.Success("Config", "Passed without errors.");

sLog.Close();

}else

{

return false;

}

g_server_id = Config.MainConfig.GetIntDefault("ServerInfo", "ServerID", 1);

g_max_connect = Config.MainConfig.GetIntDefault("ServerInfo", "MaxConnect", 500);

g_server_name = Config.MainConfig.GetStringDefault("ServerInfo", "ServerName", "PDKMainServer");

// 是否主服务器

// 连接人数上限

if (g_server_id == 1)

{

is_main_gs = true;

}

// 开始时间管理

//gTimeManager.Run();

// 设置日志级别

sLog.Init(0, GAMEFRAME_LOG);

sLog.outBasic(BANNER, BUILD_TAG, BUILD_HASH_STR, CONFIG, PLATFORM_TEXT, ARCH);

sLog.outErrorSilent(BANNER, BUILD_TAG, BUILD_HASH_STR, CONFIG, PLATFORM_TEXT, ARCH); // Echo off.

// 初始化随机种子

InitRAndomNumberGenerators();

new CPlayerManager;

new CRoomManager;

new CModuleManager;

new CAccountManager;

//new CMatchManager;

new CMatchManager;

ThreadPool.Startup();

//// 初始化DB

//if(!_StartDB())

//{

// Database::CleanupLibs();

// sLog.Close();

// return false;

//}

//// 检查DB版本 暂不处理

//if(!CheckDBVersion())

//{

// sLog.Close();

// return false;

//}

//// 清理数据库 暂不处理

//if(do_database_clean)

//{

// sLog.outDebug("Entering database maintenance mode.");

// new DatabaseCleaner;

// DatabaseCleaner::getSingleton().Run();

// Delete DatabaseCleaner::getSingletonPtr();

// sLog.outDebug("Maintenance finished.");

//}

////事件处理机制 暂不加入

//new EventMgr;

new CSessionsManager;

int LogLevel = Config.MainConfig.GetIntDefault("LogLevel", "FileLogLevel", 2);

sLog.SetFileLoggingLevel(LogLevel);

//CGameFrameSession::InitPacketHAndlerTable();

GameRunnable* gr = new GameRunnable();

ThreadPool.ExecuteTask(gr);

new SocketMgr;

new SocketGarbageCollector;

RegisterProtocols();

string host = Config.MainConfig.GetStringDefault("Listen", "Host", DEFAULT_HOST);

int wsport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", DEFAULT_SERVER_PORT);



new ServerConnect();

sServerConnect.Startup();

ListenSocket<ClientSocket> * cl = new ListenSocket<ClientSocket>(host.c_str(), wsport);

sSocketMgr.SpawnWorkerThreads();

bool authsockCreated = cl->IsOpen();

if(authsockCreated )

{

#ifdef WIN32

ThreadPool.ExecuteTask(cl);

#endif

sLog.outString("Hooking signals...");

signal(SIGINT, _OnSignal);

signal(SIGTERM, _OnSignal);

signal(SIGABRT, _OnSignal);

#ifdef _WIN32

signal(SIGBREAK, _OnSignal);

#else

signal(SIGHUP, _OnSignal);

#endif

/* write pid file */

FILE* fPid = fopen("logonserver.pid", "w");

if(fPid)

{

uint32 pid;

#ifdef WIN32

pid = GetCurrentProcessId();

#else

pid = getpid();

#endif

fprintf(fPid, "%", (unsigned int)pid);

fclose(fPid);

}

uint32 loop_counter = 0;

//ThreadPool.Gobble();

sLog.outString("Success! Ready fOrconnections");

while(mrunning.GetVal())

{

loop_counter++;

if (!(loop_counter %2)) // 2s

{

//sAccountMgr.CheckUpdate();

}

if(!(loop_counter %5))

{

//sInfoCore.TimeoutSockets();

sSocketGarbageCollector.Update();

//sSessionsManager.CheckPing();

//CheckForDeadSockets(); // Flood Protection

UNIXTIME = time(NULL);

g_localTime = *localtime(&UNIXTIME);

}

if (!(loop_counter %600)) // 10mins

{

//sAccountMgr.CheckDelete();

}

if(!(loop_counter %300)) // 5mins

{

ThreadPool.IntegrityCheck();

}

if(!(loop_counter %5))

{

UNIXTIME = time(NULL);

g_localTime = *localtime(&UNIXTIME);

}

Arcemu::Sleep(1000);

}

sLog.outString("Shutting down...");

signal(SIGINT, 0);

signal(SIGTERM, 0);

signal(SIGABRT, 0);

#ifdef _WIN32

signal(SIGBREAK, 0);

#else

signal(SIGHUP, 0);

#endif

}

else

{

LOG_ERROR("ErrOrcreating sockets. Shutting down...");

}

gr->SetThreadState(THREADSTATE_TERMINATE);

cl->Close();

sSocketMgr.CloseAll();

#ifdef WIN32

sSocketMgr.ShutdownThreads();

#endif

// kill db

sLog.outString("Waiting fOrdatabase to close..");

ThreadPool.Shutdown();

Delete ServerConnect::getSingletonPtr();

// Delete pid file

remove("logonserver.pid");

Delete SocketMgr::getSingletonPtr();

Delete SocketGarbageCollector::getSingletonPtr();

Delete CSessionsManager::getSingletonPtr();

Delete CMatchManager::getSingletonPtr();

Delete cl;

UnregisterProtocols();

LOG_BASIC("Shutdown complete.");

sLog.Close();

Delete CModuleManager::getSingletonPtr();

Delete CRoomManager::getSingletonPtr();

Delete CPlayerManager::getSingletonPtr();

//string host = Config.MainConfig.GetStringDefault("Listen", "Host", DEFAULT_HOST);

//int wsport = Config.MainConfig.GetIntDefault("Listen", "WorldServerPort", DEFAULT_WORLDSERVER_PORT);

return true;

总结

网络模块分两部分,一个是跟账号服务器通信的ServerConnect,一个是跟客户端通信的ListenSocket<ClientSocket>,网络模块获取的数据都放到Session里面CSessionsManager类负责管理,CGameLogic游戏逻辑是在GameRunnable线程中运行的



转自:http://www.dcscms.com/article/content.php?seq=21

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: