首页 > 代码库 > 游戏服务器架构分析

游戏服务器架构分析

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

游戏服务器逻辑架构图

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

游戏服务器程序框架图

程序入口代码

// 读取此服务器相关配置  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

游戏服务器架构分析