/** * @file gatesrv.cpp * @brief gatesrv主文件 * Copyright(c) 2007,上海第九城市游戏研发部 * All rights reserved * 文件名称:gatesrv.cpp * 摘 要:gatesrv主程序 * 作 者:dzj * 完成日期:2007.11.20 */ #include "stdafx.h" #include "ace/OS_main.h" #include "ace/Thread_Manager.h" #include "BufQueue/BufQueueImp.h" #include "Utility.h" #include "PkgProc/RcvPkgHandler.h" //收包处理器(CRcvPkgHandler); #include "PkgProc/CManCommHandler.h" //所有连接管理器; //网络模块需要; #include "NetTask.h" #include "HandlerT.h" #include "Player/Player.h" //给客户端收包处理器提供包处理者; #include "OtherServer/otherserver.h" //给其它srv收包处理器提供包处理者; TCache< MsgToPut >* g_poolMsgToPut; const unsigned char SELF_PROTO_TYPE = 0x01;//自身为GateSrv,定义见srvProtocol.h; #define CLI_PKGPROCER_TYPE CPlayer //客户端包处理者; #define CLI_HANDLER_TYPE CRcvPkgHandler< CLI_PKGPROCER_TYPE > //客户端通信处理器类型; #define CLI_HANDLER_POOL_TYPE TCache< CLI_HANDLER_TYPE > //客户端处理器内存池类型; #define SRV_PKGPROCER_TYPE COtherServer //客户端包处理者; #define SRV_HANDLER_TYPE CRcvPkgHandler< SRV_PKGPROCER_TYPE > //客户端通信处理器类型; #define SRV_HANDLER_POOL_TYPE TCache< SRV_HANDLER_TYPE > //客户端处理器内存池类型; ///向客户端发包的队列; IBufQueue* g_pClientSender;//向客户端发包的队列; ///向服务器其它srv发包的队列; IBufQueue* g_pSrvSender;//向服务器其它srv发包的队列; CLI_HANDLER_POOL_TYPE* g_poolCliRcvPkgHandler;//客户端处理器内存池; SRV_HANDLER_POOL_TYPE* g_poolSrvRcvPkgHandler;//服务器其它Srv处理器内存池; bool g_bKickAllPlay = false; class CMyNetHandler : public CHandlerT { public: /// 缺省 CMyNetHandler(void){} int onLinkUp(void) { ACE_INET_Addr remoteAddr; getRemoteAddress(remoteAddr); ACE_INET_Addr localAddr; this->peer().get_local_addr( localAddr ); D_DEBUG( "连接成功,自身地址(%s:%d)\n", localAddr.get_host_addr(), localAddr.get_port_number() ); D_DEBUG( " 对端地址(%s:%d)\n", remoteAddr.get_host_addr(), remoteAddr.get_port_number() ); return 0; } int onLinkDown(void) { ACE_INET_Addr remoteAddr; getRemoteAddress(remoteAddr); D_DEBUG("连接断开,客户信息(%s:%d)\n", remoteAddr.get_host_addr(), remoteAddr.get_port_number()); return 0; } int handlePackage(char* pszPack, unsigned int uiPakcLen) { ACE_UNUSED_ARG( uiPakcLen ); if(pszPack == NULL) return -1; // 设置附加信息 MsgToPut *pMsgToPut = (MsgToPut *)pszPack; #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable: 4311 ) //"type cast" pointer truncation from ??* to ?? pMsgToPut->nHandleID = (int)this->peer().get_handle(); #pragma warning( pop ) #else //ACE_WIN32 pMsgToPut->nHandleID = (int)this->peer().get_handle(); #endif //ACE_WIN32 pMsgToPut->nSessionID = this->sessionID(); // 插入已读队列 this->readQueue()->PushMsg(pMsgToPut); return 0; } }; void ConnectMapSrv( IBufQueue* pSendQueue ) { if ( NULL != CManPlayer::GetMapserver( 700 ) ) { //如果已连接,则不再重连; return; } //以下连接mapsrv //* ACE_Event_Handler::READ_MASK*/ MsgToPut* tmpMsg = g_poolMsgToPut->RetrieveOrCreate(); tmpMsg->nSessionID = 700;//mapsrv0 tmpMsg->nHandleID = 0; tmpMsg->nMsgLen = -1;//连接服务器; char mapsrvaddr[] = "172.18.9.188:6801"; #ifdef ACE_WIN32 strcpy_s( tmpMsg->pMsg, sizeof(tmpMsg->pMsg), mapsrvaddr ); #else //ACE_WIN32 strcpy( tmpMsg->pMsg, mapsrvaddr ); #endif //ACE_WIN32 pSendQueue->PushMsg( tmpMsg ); pSendQueue->SetReadEvent(); } ///应用程序主函数; int ACE_TMAIN(int /*argc*/, ACE_TCHAR* /*argv*/[]) { TRY_BEGIN ; g_poolMsgToPut = new TCache< MsgToPut >( 3 );//全局MsgToPut对象池; g_poolCliRcvPkgHandler = new CLI_HANDLER_POOL_TYPE( 3 );//客户端收包处理器池; // g_poolSrvRcvPkgHandler = new SRV_HANDLER_POOL_TYPE( 3 );//服务端收包处理器池; IBufQueue* pClientReadQueue = new CBufQueue;//从此队列读客户端网络消息; IBufQueue* pClientWriteQueue = new CBufQueue;//向此队列写客户端网络消息; g_pClientSender = pClientWriteQueue;//客户端发包器; //IBufQueue* pSrvReadQueue = new CBufQueue;//从此队列读其它srv网络消息; //IBufQueue* pSrvWriteQueue = new CBufQueue;//向此队列写其它srv网络消息; //g_pSrvSender = pClientWriteQueue;//其它srv发包器; // 激活任务 CNetTask cliTask(pClientReadQueue, pClientWriteQueue);//与客户端的网络通信任务; ACE_INET_Addr cliListenAddr( 6800 ); if(cliTask.open((void*)&cliListenAddr) == -1) { D_DEBUG("clitask activate error ,d=%d\n", 1); return 0; } //CNetTask srvTask(pClientReadQueue, pClientWriteQueue);//与服务端的网络通信任务; //ACE_INET_Addr srvListenAddr( 6801 ); //if(srvTask.open((void*)&srvListenAddr) == -1) //{ // D_DEBUG("srvtask activate error ,d=%d\n", 1); // return 0; //} CManCommHandler< CLI_HANDLER_TYPE >* g_ManCliCommHandler //客户端收包句柄管理; = new CManCommHandler< CLI_HANDLER_TYPE >; g_ManCliCommHandler->SetNetQueue( pClientReadQueue );//客户端收包句柄管理,置收包来源(收包队列); g_ManCliCommHandler->SetHandlePool( g_poolCliRcvPkgHandler );//客户端收包句柄管理,设置收包句柄对象池; ConnectMapSrv( g_pClientSender ); //CManCommHandler< CLI_HANDLER_TYPE >* g_ManSrvCommHandler //服务端收包句柄管理; // = new CManCommHandler< CLI_HANDLER_TYPE >; //g_ManSrvCommHandler->SetNetQueue( pSrvReadQueue );//服务端收包句柄管理,置收包来源(收包队列); //g_ManSrvCommHandler->SetHandlePool( g_poolSrvRcvPkgHandler );//服务端收包句柄管理,设置收包句柄对象池; //以下主线程继续工作,其间通过pWriteQueue、pReadQueue与网络线程通信; ACE_Time_Value stTime = ACE_OS::gettimeofday(); ACE_Time_Value curTime = ACE_OS::gettimeofday(); ACE_Time_Value pastTime; ACE_Time_Value connectMapsrvTime = ACE_OS::gettimeofday(); ACE_Time_Value connectMapsrvpassed = ACE_OS::gettimeofday() - connectMapsrvTime; while(true) { curTime = ACE_OS::gettimeofday(); pastTime = curTime - stTime; if ( pastTime.sec() > 60*90 )//1分钟; { cliTask.quit(); break; } ////////////////////////////////////////////////////////////////////////// //检查是否需要因为mapsrv断开而删去所有玩家; if ( g_bKickAllPlay ) { CManPlayer::KickAllPlayer(); g_bKickAllPlay = false; } //检查是否需要因为mapsrv断开而删去所有玩家; ////////////////////////////////////////////////////////////////////////// connectMapsrvpassed = curTime - connectMapsrvTime; if ( connectMapsrvpassed.sec() > 20 )//定时重连mapserver; { connectMapsrvTime = curTime; ConnectMapSrv( g_pClientSender ); } ACE_Time_Value tmpTime;//等待一会; tmpTime.sec(0); tmpTime.usec( 600 ); ACE_OS::sleep( tmpTime ); //ACE_Thread_Manager::instance()->wait ( &tmpTime, false, false ); g_ManCliCommHandler->CommTimerProc();//网络消息处理; } // 等待任务结束 cliTask.wait(); //srvTask.wait(); //删客户端收包管理器; if ( NULL != g_ManCliCommHandler ) { delete g_ManCliCommHandler; g_ManCliCommHandler = NULL; } ////删服务端收包管理器; //if ( NULL != g_ManSrvCommHandler ) //{ // delete g_ManSrvCommHandler; g_ManSrvCommHandler = NULL; //} //删客户端发送与接收缓冲; if ( NULL != pClientReadQueue ) { delete pClientReadQueue; pClientReadQueue = NULL; } if ( NULL != pClientWriteQueue ) { delete pClientWriteQueue; pClientWriteQueue = NULL; } ////删服务端发送与接收缓冲; //if ( NULL != pSrvReadQueue ) //{ // delete pSrvReadQueue; pSrvReadQueue = NULL; //} //if ( NULL != pSrvWriteQueue ) //{ // delete pSrvWriteQueue; pSrvWriteQueue = NULL; //} //删MsgToPut对象池; if ( NULL != g_poolMsgToPut ) { delete g_poolMsgToPut; g_poolMsgToPut = NULL; } //删客户端收包处理器池; if ( NULL != g_poolCliRcvPkgHandler ) { delete g_poolCliRcvPkgHandler; g_poolCliRcvPkgHandler = NULL; } ////删服务端收包处理器池; //if ( NULL != g_poolSrvRcvPkgHandler ) //{ // delete g_poolSrvRcvPkgHandler; g_poolSrvRcvPkgHandler = NULL; //} return 0; TRY_END ; return -1; }