305 lines
7.7 KiB
C++
305 lines
7.7 KiB
C++
|
|
#include "StdAfx.h"
|
|||
|
|
#include "WinService.h"
|
|||
|
|
#include "DataProcess.h"
|
|||
|
|
#include "SockProcess.h"
|
|||
|
|
#include "SelectSockProcess.h"
|
|||
|
|
#include "IOCPSockProcess.h"
|
|||
|
|
#include "GateServer.h"
|
|||
|
|
#include "GateServerConfig.h"
|
|||
|
|
#include "FileLogger.h"
|
|||
|
|
#include <string.h>
|
|||
|
|
#ifndef WIN32
|
|||
|
|
// #include "client/linux/handler/exception_handler.h"
|
|||
|
|
#endif
|
|||
|
|
#ifndef WIN32
|
|||
|
|
DWORD GetTickCount()
|
|||
|
|
{
|
|||
|
|
struct timespec ts;
|
|||
|
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|||
|
|
return (ts.tv_sec*1000 + ts.tv_nsec/1000000);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
bool GateEngineRunning = true;
|
|||
|
|
|
|||
|
|
static void signal_handler(int sig_num)
|
|||
|
|
{
|
|||
|
|
if( sig_num == SIGHUP ||
|
|||
|
|
sig_num == SIGINT ||
|
|||
|
|
sig_num == SIGTERM )
|
|||
|
|
{
|
|||
|
|
GateEngineRunning = false;
|
|||
|
|
OutputMsg( rmTip, _T("[SIGNAL] signal(%d) signal_handler... "), sig_num);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
OutputMsg( rmError, _T("[SIGNAL] signal(%d) signal_handler... "), sig_num);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ServerMain(int argc, char** argv);
|
|||
|
|
VOID ServiceMain(int argc, char** argv);
|
|||
|
|
|
|||
|
|
bool CreateAndStartGateServers(CBaseList<CRunSockProcesser*> &gateList,char *pFileName=NULL);
|
|||
|
|
void DestroyGateServers(CBaseList<CRunSockProcesser*> &gateList);
|
|||
|
|
|
|||
|
|
//服务器是否在运行
|
|||
|
|
bool g_ServerIsRunning =true;
|
|||
|
|
|
|||
|
|
void TestMemory()
|
|||
|
|
{
|
|||
|
|
DWORD dwStart = GetTickCount();
|
|||
|
|
for(int i = 0; i < 1000000; i++) { char *p = (char*)malloc(i%1000000); free(p); }
|
|||
|
|
|
|||
|
|
DWORD dwEnd = GetTickCount();
|
|||
|
|
printf("***********************",dwEnd - dwStart);
|
|||
|
|
printf("100wMemoryTest:%d ms\n",dwEnd - dwStart);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
#ifdef WIN32
|
|||
|
|
class CGateService : public CWinService
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
CGateService(LPCSTR pServiceName, DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS):CWinService(pServiceName, dwServiceType){};
|
|||
|
|
int AppMain()
|
|||
|
|
{
|
|||
|
|
CFileLogger flog(_T("GateServer_%s.log"), getCurrentTimeDesc());
|
|||
|
|
CBaseList<CRunSockProcesser*> gateList;
|
|||
|
|
SetCurrentDirectory("../"); //CWinService里会把当前目录改成exe允许的目录,所以这里再转一下
|
|||
|
|
|
|||
|
|
|
|||
|
|
if ( CreateAndStartGateServers(gateList) )
|
|||
|
|
{
|
|||
|
|
in_addr ia;
|
|||
|
|
ia.s_addr = RUNGATE_KRN_VERSION;
|
|||
|
|
|
|||
|
|
OutputMsg( rmTip, _T("-------------------------------------------") );
|
|||
|
|
OutputMsg( rmTip, _T("网关服务器启动成功,核心版本号是%s"), inet_ntoa(ia) );
|
|||
|
|
OutputMsg( rmTip, _T("quit命令可以停止服务并退出程序") );
|
|||
|
|
OutputMsg( rmTip, _T("-------------------------------------------") );
|
|||
|
|
while (!m_boServiceExit)
|
|||
|
|
{
|
|||
|
|
Sleep(1000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
DestroyGateServers(gateList);
|
|||
|
|
Sleep(2000);//休眠一秒等待日志全部刷新到文件
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
int main(int argc, char **argv)
|
|||
|
|
{
|
|||
|
|
//TestMemory();
|
|||
|
|
#ifdef WIN32
|
|||
|
|
SetUnhandledExceptionFilter( DefaultUnHandleExceptionFilter );
|
|||
|
|
#endif
|
|||
|
|
(void)signal(SIGHUP, SIG_IGN);
|
|||
|
|
(void)signal(SIGINT, signal_handler);
|
|||
|
|
(void)signal(SIGTERM, signal_handler);
|
|||
|
|
InitDefMsgOut();
|
|||
|
|
CTimeProfMgr::getSingleton().InitMgr();
|
|||
|
|
winitseed((unsigned int)_getTickCount()); //初始化随机数函数
|
|||
|
|
|
|||
|
|
#ifndef _SERVICE
|
|||
|
|
//if (argc == 2 && strncmp("/cmd",argv[1],4)==0)//平时调试用
|
|||
|
|
{
|
|||
|
|
#ifdef WIN32
|
|||
|
|
SetCurrentDirectory("./");
|
|||
|
|
#else
|
|||
|
|
std::string filename(argv[0]);
|
|||
|
|
size_t found = filename.find_last_of("/\\");
|
|||
|
|
filename = filename.substr(0, found);
|
|||
|
|
if( filename[0] == '.' && filename.length()==1 )
|
|||
|
|
filename = "./" ;
|
|||
|
|
SetCurrentDirectory(filename.c_str());
|
|||
|
|
#endif
|
|||
|
|
ServerMain(argc, argv);
|
|||
|
|
}
|
|||
|
|
#else
|
|||
|
|
//else
|
|||
|
|
{
|
|||
|
|
ServiceMain(argc, argv);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
UninitDefMsgOut();
|
|||
|
|
|
|||
|
|
#ifdef _MLIB_DUMP_MEMORY_LEAKS_
|
|||
|
|
_CrtDumpMemoryLeaks();
|
|||
|
|
#endif
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#ifdef WIN32
|
|||
|
|
VOID ServiceMain(int argc, char** argv)
|
|||
|
|
{
|
|||
|
|
LPTSTR sCmd = NULL;
|
|||
|
|
if (argc >= 2)
|
|||
|
|
{
|
|||
|
|
sCmd = argv[1];
|
|||
|
|
}
|
|||
|
|
CGateService service("GateService");
|
|||
|
|
|
|||
|
|
service.Run(sCmd);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
void ServerMain(int argc, char **argv)
|
|||
|
|
{
|
|||
|
|
CFileLogger flog(_T("../log/GateServer_%s.log"), getCurrentTimeDesc());
|
|||
|
|
CBaseList<CRunSockProcesser*> gateList;
|
|||
|
|
|
|||
|
|
char *pFileName =NULL;
|
|||
|
|
if(argc >=2)
|
|||
|
|
{
|
|||
|
|
pFileName = argv[1];
|
|||
|
|
}else
|
|||
|
|
{
|
|||
|
|
pFileName="GateServerLinux.txt";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ( CreateAndStartGateServers(gateList,pFileName) )
|
|||
|
|
{
|
|||
|
|
TCHAR sCmdBuf[512];
|
|||
|
|
in_addr ia;
|
|||
|
|
ia.s_addr = RUNGATE_KRN_VERSION;
|
|||
|
|
|
|||
|
|
OutputMsg( rmTip, _T("-------------------------------------------") );
|
|||
|
|
OutputMsg( rmTip, _T("网关服务器启动成功,核心版本号是%s"), inet_ntoa(ia) );
|
|||
|
|
OutputMsg( rmTip, _T("spf命令可以查看当前的网关状态") );
|
|||
|
|
OutputMsg( rmTip, _T("quit命令可以停止服务并退出程序") );
|
|||
|
|
OutputMsg( rmTip, _T("-------------------------------------------") );
|
|||
|
|
|
|||
|
|
while (g_ServerIsRunning)
|
|||
|
|
{
|
|||
|
|
#ifdef WIN32
|
|||
|
|
if(_kbhit())
|
|||
|
|
{
|
|||
|
|
_getts(sCmdBuf);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Sleep(100);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
if ( strncmp(sCmdBuf, _T("\\q"), 2) == 0
|
|||
|
|
|| strncmp(sCmdBuf, _T("exit"), 4) == 0
|
|||
|
|
|| strncmp(sCmdBuf, _T("quit"), 4) == 0 )
|
|||
|
|
{
|
|||
|
|
OutputMsg( rmTip, _T("正在停止网关服务...") );
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
else if ( strncmp(sCmdBuf, _T("spf"), 3) == 0 ) // 需要刷
|
|||
|
|
{
|
|||
|
|
for (INT_PTR i=0; i< gateList.count(); ++i)
|
|||
|
|
{
|
|||
|
|
CRunDataProcesser::ShowGateStatus(gateList[i]->GetDataProcesser());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CTimeProfMgr::getSingleton().dump();
|
|||
|
|
}
|
|||
|
|
else if (strncmp(sCmdBuf, _T("stst"), 4) == 0) // stst 10(ms为单位)
|
|||
|
|
{
|
|||
|
|
char *pParam = sCmdBuf + 4;
|
|||
|
|
while (*pParam == ' ')
|
|||
|
|
pParam++;
|
|||
|
|
if (pParam)
|
|||
|
|
{
|
|||
|
|
UINT_PTR nInterval = atoi(pParam);
|
|||
|
|
if (nInterval > 0)
|
|||
|
|
{
|
|||
|
|
CRunDataProcesser::s_nSndThreadSleepTime = (unsigned int)nInterval;
|
|||
|
|
OutputMsg(rmNormal, _T("Set SndThreadSleepTime[%d ms] Succ"), nInterval);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if(strncmp(sCmdBuf, _T("ignore"), 6) == 0)
|
|||
|
|
{
|
|||
|
|
CRunDataProcesser::s_nIgnoreDataPacket = 1;
|
|||
|
|
}
|
|||
|
|
else if(strncmp(sCmdBuf, _T("resume"), 6) == 0)
|
|||
|
|
{
|
|||
|
|
CRunDataProcesser::s_nIgnoreDataPacket = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#else
|
|||
|
|
if(!GateEngineRunning) break;
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
Sleep(10);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
DestroyGateServers(gateList);
|
|||
|
|
Sleep(2000);//休眠一秒等待日志全部刷新到文件
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool CreateAndStartGateServers(CBaseList<CRunSockProcesser*> &gateList,char *pConfig)
|
|||
|
|
{
|
|||
|
|
CGateConfigList configList;
|
|||
|
|
CGateServerConfig configReader;
|
|||
|
|
CRunSockProcesser *pRunSock;
|
|||
|
|
CRunDataProcesser *pRunData;
|
|||
|
|
|
|||
|
|
if ( configReader.loadConfig(configList,pConfig) )
|
|||
|
|
{
|
|||
|
|
INT_PTR i, nCount = configList.count();
|
|||
|
|
PGATECONFIG pConfigList = configList;
|
|||
|
|
for (i=0; i<nCount; ++i)
|
|||
|
|
{
|
|||
|
|
//创建并配置网关后台服务数据处理器
|
|||
|
|
pRunData = new CRunDataProcesser(__max(1024, pConfigList[i].GateServer.nMaxSession));
|
|||
|
|
pRunData->SetSendThreadCount( __max(1,pConfigList[i].GateServer.SendThreadCount) );
|
|||
|
|
pRunData->SetDataProcessType(dp_Default);
|
|||
|
|
pRunData->SetServerHost(pConfigList[i].BackServer.sHost);
|
|||
|
|
pRunData->SetServerPort(pConfigList[i].BackServer.nPort);
|
|||
|
|
pRunData->SetName(pConfigList[i].GateServer.sName);
|
|||
|
|
//创建并配置网关用户服务器处理器
|
|||
|
|
pRunSock = new CSelectRunSockProcesser();
|
|||
|
|
pRunSock->SetBindAddress( pConfigList[i].GateServer.sAddress );
|
|||
|
|
pRunSock->SetBindPort( pConfigList[i].GateServer.nPort );
|
|||
|
|
pRunSock->SetDataProcesser(pRunData);
|
|||
|
|
pRunData->SetRunSockProcesser(pRunSock);
|
|||
|
|
//将网关添加到列表中
|
|||
|
|
gateList.add(pRunSock);
|
|||
|
|
//启动网关
|
|||
|
|
if ( !pRunSock->InitBase() || !pRunData->Startup() || !pRunSock->Start() )
|
|||
|
|
{
|
|||
|
|
OutputMsg(rmError, _T("Start GateServer[%s] Failed"), pConfigList[i].GateServer.sName);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
OutputMsg(rmTip, _T("GateServer[%s] Started"), pConfigList[i].GateServer.sName);
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DestroyGateServers(CBaseList<CRunSockProcesser*> &gateList)
|
|||
|
|
{
|
|||
|
|
CRunSockProcesser *pRunSock;
|
|||
|
|
CRunDataProcesser *pRunData;
|
|||
|
|
INT_PTR i, nCount = gateList.count();
|
|||
|
|
|
|||
|
|
for (i=0; i<nCount; ++i)
|
|||
|
|
{
|
|||
|
|
//停止网关用户服务器处理器
|
|||
|
|
pRunSock = gateList[i];
|
|||
|
|
pRunSock->Stop();
|
|||
|
|
//停止网关后台服务数据处理器
|
|||
|
|
pRunData = pRunSock->GetDataProcesser();
|
|||
|
|
pRunData->Stop();
|
|||
|
|
//销毁网关对象
|
|||
|
|
pRunSock->SetDataProcesser(NULL);
|
|||
|
|
OutputMsg(rmTip, _T("GateServer[%s] Stoped"), pRunData->GetName());
|
|||
|
|
delete pRunSock;
|
|||
|
|
delete pRunData;
|
|||
|
|
}
|
|||
|
|
gateList.empty();
|
|||
|
|
}
|