uint32 THREADCALL SocketMgr::SocketWorkerThread(void * lpParam) { SocketMgr *socketMgr = (SocketMgr *)lpParam; HANDLE cp = socketMgr->GetCompletionPort(); DWORD len; Socket * s = nullptr; OverlappedStruct * ov = nullptr; LPOVERLAPPED ol_ptr; while (socketMgr->m_bWorkerThreadsActive) { if (!GetQueuedCompletionStatus(cp, &len, (LPDWORD)&s, &ol_ptr, INFINITE)) { if (s != nullptr) s->Disconnect(); continue; } ov = CONTAINING_RECORD(ol_ptr, OverlappedStruct, m_overlap); if (ov->m_event == SOCKET_IO_THREAD_SHUTDOWN) { delete ov; return 0; } if (ov->m_event < NUM_SOCKET_IO_EVENTS) ophandlers[ov->m_event](s, len); } return 0; }
DWORD WINAPI SocketWorkerThread(LPVOID lpParam) { SocketMgr *socketMgr = (SocketMgr *)lpParam; HANDLE cp = socketMgr->GetCompletionPort(); DWORD len; Socket * s; OverlappedStruct * ov; LPOVERLAPPED ol_ptr; while (true) { #ifndef _WIN64 if (!GetQueuedCompletionStatus(cp, &len, (LPDWORD)&s, &ol_ptr, INFINITE)) #else if (!GetQueuedCompletionStatus(cp, &len, (PULONG_PTR)&s, &ol_ptr, INFINITE)) #endif { if (s != NULL) s->Disconnect(); continue; } ov = CONTAINING_RECORD(ol_ptr, OverlappedStruct, m_overlap); if (ov->m_event == SOCKET_IO_THREAD_SHUTDOWN) { delete ov; return 0; } if (ov->m_event < NUM_SOCKET_IO_EVENTS) ophandlers[ov->m_event](s, len); } return 0; }
bool GameServer::Init() { char path[256] = ""; ::GetCurrentDirectory(sizeof(path),path); string m_CfgPath = path; m_CfgPath += "/GameServer.ini"; char tmp[1024]; ::GetPrivateProfileString( "GameServer", "Id", "1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_GameServerId = ::atoi( tmp ); ::GetPrivateProfileString( "AccountServer", "IP", "127.0.0.1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_AccountServerIP = tmp; ::GetPrivateProfileString( "AccountServer", "Port", "20003", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_AccountServerPort = (uint16)::atoi( tmp ); ::GetPrivateProfileString( "DbServer", "IP", "127.0.0.1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_DbServerIP = tmp; ::GetPrivateProfileString( "DbServer", "Port", "20004", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_DbServerPort = (uint16)::atoi( tmp ); ::GetPrivateProfileString( "Client", "ListenIP", "127.0.0.1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_ClientListenIP = tmp; ::GetPrivateProfileString( "Client", "ListenPort", "20001", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_ClientListenPort = (uint16)::atoi( tmp ); ::GetPrivateProfileString( "Client", "MaxConnection", "10", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_ClientMaxConnection = ::atoi( tmp ); new World(); World::getSingleton().LoadMaps(); SocketMgr* sockMgr = new SocketMgr(); sockMgr->AddSocketListener( 1, this, m_ClientMaxConnection, 1024*50, 1024*10, 1024*1024*5, 1024*1024, true ); /// connect to AccountServer m_AccountHandler.m_GameServer = this; if( !sockMgr->AddSocketConnector( 10000, &m_AccountHandler, m_AccountServerIP.c_str(), m_AccountServerPort, 1024*100, 1024*100, 1024*1024, 1024*1024, true ) ) { LogInfo( "Connect AccountServer Failed, Ip=%s Port=%d", m_AccountServerIP.c_str(), m_AccountServerPort ); return false; } else { LogInfo( "Connect AccountServer OK, Ip=%s Port=%d", m_AccountServerIP.c_str(), m_AccountServerPort ); } /// connect to DbServer m_DbHandler.m_GameServer = this; if( !sockMgr->AddSocketConnector( 10001, &m_DbHandler, m_DbServerIP.c_str(), m_DbServerPort, 1024*100, 1024*100, 1024*1024, 1024*1024, true ) ) { LogInfo( "Connect DbServer Failed, Ip=%s Port=%d", m_DbServerIP.c_str(), m_DbServerPort ); return false; } else { LogInfo( "Connect DbServer OK, Ip=%s Port=%d", m_DbServerIP.c_str(), m_DbServerPort ); } sockMgr->StartIOCP( 0 ); if( !sockMgr->StartListen( 1, m_ClientListenIP.c_str(), m_ClientListenPort ) ) { LogInfo( "Listen Client failed, ListenIp=%s ListenPort=%d MaxConnection=%d", m_ClientListenIP.c_str(), m_ClientListenPort, m_ClientMaxConnection ); return false; } else { LogInfo( "Listen Client OK, ListenIp=%s ListenPort=%d MaxConnection=%d", m_ClientListenIP.c_str(), m_ClientListenPort, m_ClientMaxConnection ); } Packet_GS2A_Inner_GameServerInfo packetGameServerInfo; packetGameServerInfo.m_GameServerId = m_GameServerId; m_AccountHandler.SendPacket( &packetGameServerInfo ); Packet_GS2D_Inner_GameServerInfo packetGameServerInfo2DB; packetGameServerInfo2DB.m_GameServerId = m_GameServerId; m_DbHandler.SendPacket( &packetGameServerInfo2DB ); return true; }
bool SocketWorkerThread::runThread() { //printf("Worker thread started.\n"); int fd_count; running = true; Socket* ptr; int i; struct kevent ev; struct timespec ts; ts.tv_nsec = 0; ts.tv_sec = 5; struct kevent ev2; SocketMgr* mgr = SocketMgr::getSingletonPtr(); int kq = mgr->GetKq(); while(running) { fd_count = kevent(kq, NULL, 0, &events[0], THREAD_EVENT_SIZE, &ts); for(i = 0; i < fd_count; ++i) { if(events[i].ident >= SOCKET_HOLDER_SIZE) { LogWarning("kqueue : Requested FD that is too high (%u)", events[i].ident); continue; } ptr = mgr->fds[events[i].ident]; if(ptr == NULL) { if((ptr = ((Socket*)mgr->listenfds[events[i].ident])) != NULL) { ((ListenSocketBase*)ptr)->OnAccept(); } else { LogWarning("kqueue : Returned invalid fd (no pointer) of FD %u", events[i].ident); /* make sure it removes so we don't go chasing it again */ EV_SET(&ev, events[i].ident, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); EV_SET(&ev2, events[i].ident, EVFILT_READ, EV_DELETE, 0, 0, NULL); kevent(kq, &ev, 1, 0, 0, NULL); kevent(kq, &ev2, 1, 0, 0, NULL); } continue; } if(events[i].flags & EV_EOF || events[i].flags & EV_ERROR) { ptr->Disconnect(); continue; } else if(events[i].filter == EVFILT_WRITE) { ptr->BurstBegin(); // Lock receive mutex ptr->WriteCallback(); // Perform actual send() if(ptr->writeBuffer.GetSize() > 0) ptr->PostEvent(EVFILT_WRITE, true); // Still remaining data. else { ptr->DecSendLock(); ptr->PostEvent(EVFILT_READ, false); } ptr->BurstEnd(); // Unlock } else if(events[i].filter == EVFILT_READ) { ptr->ReadCallback(0); // Len is unknown at this point. if(ptr->writeBuffer.GetSize() > 0 && ptr->IsConnected() && !ptr->HasSendLock()) { ptr->PostEvent(EVFILT_WRITE, true); ptr->IncSendLock(); } } } } return true; }
bool CenterServer::Init() { char path[256] = ""; ::GetCurrentDirectory(sizeof(path),path); string m_CfgPath = path; m_CfgPath += "/CenterServer.ini"; char tmp[1024]; ::GetPrivateProfileString( "CenterServer", "Id", "1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_CenterId = ::atoi( tmp ); ::GetPrivateProfileString( "CenterServer", "MaxMapId", "32", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_MapArraySize = ::atoi( tmp ); ::GetPrivateProfileString( "GateServer", "ListenIP", "127.0.0.1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_GateListenIP = tmp; ::GetPrivateProfileString( "GateServer", "ListenPort", "20001", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_GateListenPort = (uint16)::atoi( tmp ); ::GetPrivateProfileString( "GateServer", "MaxConnection", "10", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_GateMaxConnection = ::atoi( tmp ); ::GetPrivateProfileString( "MapServer", "ListenIP", "127.0.0.1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_MapListenIP = tmp; ::GetPrivateProfileString( "MapServer", "ListenPort", "20002", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_MapListenPort = (uint16)::atoi( tmp ); ::GetPrivateProfileString( "MapServer", "MaxConnection", "100", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_MapMaxConnection = ::atoi( tmp ); ::GetPrivateProfileString( "AccountServer", "IP", "127.0.0.1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_AccountServerIP = tmp; ::GetPrivateProfileString( "AccountServer", "Port", "20003", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_AccountServerPort = (uint16)::atoi( tmp ); ::GetPrivateProfileString( "DbServer", "IP", "127.0.0.1", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_DbServerIP = tmp; ::GetPrivateProfileString( "DbServer", "Port", "20004", tmp, sizeof(tmp), m_CfgPath.c_str() ); m_DbServerPort = (uint16)::atoi( tmp ); m_Maps = new MapHandler*[m_MapArraySize]; for( int i=0; i<m_MapArraySize; ++i ) m_Maps[i] = 0; m_MapServerListener = new MapServerListener( this ); SocketMgr* sockMgr = new SocketMgr(); sockMgr->AddSocketListener( 1, this, m_GateMaxConnection, 1024*50, 1024*10, 1024*1024*5, 1024*1024, true ); sockMgr->AddSocketListener( 2, m_MapServerListener, m_MapMaxConnection, 1024*50, 1024*50, 1024*1024, 1024*1024, true ); /// connect to AccountServer m_AccountHandler.m_CenterServer = this; if( !sockMgr->AddSocketConnector( 10000, &m_AccountHandler, m_AccountServerIP.c_str(), m_AccountServerPort, 1024*100, 1024*100, 1024*1024, 1024*1024, true ) ) { LogInfo( "Connect AccountServer Failed, Ip=%s Port=%d", m_AccountServerIP.c_str(), m_AccountServerPort ); return false; } else { LogInfo( "Connect AccountServer OK, Ip=%s Port=%d", m_AccountServerIP.c_str(), m_AccountServerPort ); } /// connect to DbServer m_DbHandler.m_CenterServer = this; if( !sockMgr->AddSocketConnector( 10001, &m_DbHandler, m_DbServerIP.c_str(), m_DbServerPort, 1024*100, 1024*100, 1024*1024, 1024*1024, true ) ) { LogInfo( "Connect DbServer Failed, Ip=%s Port=%d", m_DbServerIP.c_str(), m_DbServerPort ); return false; } else { LogInfo( "Connect DbServer OK, Ip=%s Port=%d", m_DbServerIP.c_str(), m_DbServerPort ); } sockMgr->StartIOCP( 0 ); if( !sockMgr->StartListen( 1, m_GateListenIP.c_str(), m_GateListenPort ) ) { LogInfo( "Listen Gate failed, ListenIp=%s ListenPort=%d MaxConnection=%d", m_GateListenIP.c_str(), m_GateListenPort, m_GateMaxConnection ); return false; } else { LogInfo( "Listen Gate OK, ListenIp=%s ListenPort=%d MaxConnection=%d", m_GateListenIP.c_str(), m_GateListenPort, m_GateMaxConnection ); } if( !sockMgr->StartListen( 2, m_MapListenIP.c_str(), m_MapListenPort ) ) { LogInfo( "Listen Map failed, ListenIp=%s ListenPort=%d MaxConnection=%d", m_MapListenIP.c_str(), m_MapListenPort, m_MapMaxConnection ); return false; } else { LogInfo( "Listen Map OK, ListenIp=%s ListenPort=%d MaxConnection=%d", m_MapListenIP.c_str(), m_MapListenPort, m_MapMaxConnection ); } Packet_CS2A_Inner_CenterInfo packetCenterInfo; packetCenterInfo.m_CenterId = m_CenterId; m_AccountHandler.SendPacket( &packetCenterInfo ); Packet_CS2D_Inner_CenterInfo packetCenterInfo2DB; packetCenterInfo2DB.m_CenterId = m_CenterId; m_DbHandler.SendPacket( &packetCenterInfo2DB ); return true; }