游戏服务器架构分析
2014-11-30 00:36
357 查看
记录下我们游戏服务器的架构
// 读取此服务器相关配置
// 开始时间管理
sLog.outBasic(BANNER, BUILD_TAG, BUILD_HASH_STR, CONFIG, PLATFORM_TEXT, ARCH);
//// 初始化DB
//// 检查DB版本 暂不处理
//// 清理数据库 暂不处理
////事件处理机制 暂不加入
int LogLevel = Config.MainConfig.GetIntDefault("LogLevel", "FileLogLevel", 2);
//CGameFrameSession::InitPacketHAndlerTable();
GameRunnable* gr = new GameRunnable();
string host = Config.MainConfig.GetStringDefault("Listen", "Host", DEFAULT_HOST);
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;
记录下我们游戏服务器的架构
游戏服务器逻辑架构图
我自己设计的游戏逻辑架构图
游戏服务器程序框架图
程序入口代码
// 读取此服务器相关配置
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
相关文章推荐
- 《从零开始搭建游戏服务器》架构和工具分析
- 《从零开始搭建游戏服务器》架构和工具分析
- 开源内容管理Fedora架构分析!
- 当前流行的J2EE WEB应用架构分析
- 应用架构设计与分析相关资料的收集、总结与复习(动态更新)
- Duwamish架构分析篇
- NV GF6系列架构分析(GPU gem2 读书笔记)
- 需求分析与企业信息架构
- nhibernate架构分析(uml图)
- Duwamish架构分析篇
- 泡泡堂、QQ堂游戏通信架构分析
- 中国顶级门户网站架构分析1
- 当前流行的J2EE WEB应用架构分析
- 中国顶级门户网站架构分析
- 整合Hibernate的EJB架构分析
- 企业应用架构研究与分析
- 中国顶级门户网站架构分析 2
- Duwamish架构分析篇
- Duwamish架构分析篇 (转)
- 微软.NET经典架构例程Duwamish 7.0分析