#include "stdafx.h" #include "resource.h" #include "StatServer.h" #include "StatServerDispatch.h" #include #include #include // CNamedMutex #include #include // g_CExceptionReport #include #include #include #include #include #include #include #include #include "StatisticsDB.h" int WINAPI ExceptionUserFunc(char* szBuffer, int nBufferLen) { g_Log.Flush(); g_SessionLog.Flush(); return _snprintf(szBuffer, nBufferLen, "Exception Occured. Flush all buffers."); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { /* CNamedMutex Mutex("StatServer", TRUE); if(GetLastError() == ERROR_ALREADY_EXISTS) { ERRLOG0(g_Log, "StatServer already server operating now. please shutdown and restart"); return 0; } */ unsigned long dwExceptionFeatures = CExceptionReport::CATCH_EXCEPTION | CExceptionReport::USE_MINIDUMP | CExceptionReport::USE_REPORT; CExceptionReport::GetInstance().Enable(dwExceptionFeatures); CExceptionReport::GetInstance().SetUserFunc(ExceptionUserFunc); CStatServer& StatServer = CStatServer::GetInstance(); if(StatServer.Initialize(hInstance, "StatServer", lpCmdLine, IDI_STATSERVER, IDC_STATSERVER)) { StatServer.ProcessMessage(); } return 0; } class CStatServerProcessThread : public CProcessThread { public: enum Const { PROCESS_TPP = 200, // 200ms(0.2ÃÊ) ¿¡ 1ƽ. TPP_PER_SEC = 1000 / PROCESS_TPP, CONNECT_CHECK = 2 * TPP_PER_SEC, // 2Ãʸ¶´Ù ¿¬°á üũ PRINT_CONSOLE = 2 * TPP_PER_SEC, // 2Ãʸ¶´Ù ÄܼÖâ °»½Å }; CStatServerProcessThread(CStatServer& StatServer) : CProcessThread(StatServer, PROCESS_TPP) , m_StatServer(StatServer) { } ~CStatServerProcessThread() { } private: virtual void InternalRun(CPulse& Pulse) { unsigned long dwCurrentPulse = Pulse.GetCurrentPulse(); if(0 == (dwCurrentPulse % CONNECT_CHECK)) { } if(0 == (dwCurrentPulse % PRINT_CONSOLE)) { m_StatServer.UpdateConsole(); } } virtual void Cleanup(CPulse& Pulse) { } CStatServer& m_StatServer; }; CStatServer& CStatServer::GetInstance() { static CStatServer StatServer; return StatServer; } CStatServer::CStatServer() : m_lpCommandQueueThread(NULL) , m_lpServerSessionPolicy(SessionPolicy::CreateTCPPolicy()) , m_tServerStart(0) { } CStatServer::~CStatServer() { if(NULL != m_lpServerSessionPolicy) { m_lpServerSessionPolicy->Release(); m_lpServerSessionPolicy = NULL; } } bool CStatServer::ApplicationSpecificInit(const TCHAR* szCmdLine) { const TCHAR* szErrorMessage = NULL; if(!GetIOCPNet()->AddListener(m_lpServerSessionPolicy, NULL, CServerSetup::StatServerManageServerListen)) { szErrorMessage = _T("StatServerListener add failed"); } else if(!AddProcessThread(new CStatServerProcessThread(*this))) { szErrorMessage = _T("AddProcessThread failed(StatServerProcessThread)"); } else if(NULL == (m_lpCommandQueueThread = new CCommandQueueThread)) { szErrorMessage = _T("CCommandQueueThread create failed"); } else if(!m_lpCommandQueueThread->IsValid()) { szErrorMessage = _T("CCommandQueueThread is Invalid"); } else if(!AddProcessThread(m_lpCommandQueueThread)) { szErrorMessage = _T("AddProcessThread failed(CCommandQueueThread)"); } else if(!InitializeMsgProc()) { szErrorMessage = _T("Initialize message proc failed"); } else if(!InitializeCommand()) { szErrorMessage = _T("Initialize command failed"); } else if(!CStatisticsDB::GetInstance().ConnectStatDB()) { szErrorMessage = _T("Initialize StatDB failed"); } m_tServerStart = time(NULL); if(NULL != szErrorMessage) { ERRLOG2(g_Log, "this:0x%p / %s", this, szErrorMessage); return false; } return true; } void CStatServer::UpdateConsole() { const int MAX_INFO = 4096; char szInfo[MAX_INFO]; time_t tCurrent = time(NULL); time_t tDiffTime = tCurrent - m_tServerStart; time_t tDiffDay = tDiffTime / 3600 / 24; time_t tDiffHour = (tDiffTime / 3600) % 24; time_t tDiffMinute = (tDiffTime % 3600) / 60; struct tm tmServerStart = *localtime(&m_tServerStart); struct tm tmCurrent = *localtime(&tCurrent); int nLength = _snprintf(szInfo, MAX_INFO - 1, "[GAMA Statistics Server]\r\n\r\n" "Server Start Time : %04d-%02d-%02d %02d:%02d:%02d\r\n" "Current Server Time : %04d-%02d-%02d %02d:%02d:%02d\r\n" "\r\n" "Server Operate Time : %04d Days %02d Hours %02d Minutes", tmServerStart.tm_year + 1900, tmServerStart.tm_mon + 1, tmServerStart.tm_mday, tmServerStart.tm_hour, tmServerStart.tm_min, tmServerStart.tm_sec, tmCurrent.tm_year + 1900, tmCurrent.tm_mon + 1, tmCurrent.tm_mday, tmCurrent.tm_hour, tmCurrent.tm_min, tmCurrent.tm_sec, tDiffDay, tDiffHour, tDiffMinute); if(0 < nLength && nLength < MAX_INFO) { szInfo[nLength] = 0; PrintInfo(szInfo, nLength); } }