首页 > 代码库 > 游戏服务器架构分析
游戏服务器架构分析
记录下我们游戏服务器的架构
游戏服务器逻辑架构图
我自己设计的游戏逻辑架构图
游戏服务器程序框架图
程序入口代码
// 读取此服务器相关配置 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
游戏服务器架构分析