#include "StdAfx.h" #include "DNIocpManager.h" #include "DNConnection.h" #include "DNThreadManager.h" #include "DnServiceConnection.h" #include "Log.h" #include "DNLogConnection.h" #include "SpinBuffer.h" #if defined(_KRAZ) #include "DNActozShield.h" #endif // #if defined(_KRAZ) extern TDBConfig g_Config; CDNIocpManager* g_pIocpManager = NULL; CDNIocpManager::CDNIocpManager(void): CIocpManager() { for( int i=0 ; im_bThreadSwitch){ CurTick = timeGetTime(); if (g_pServiceConnection) g_pServiceConnection->Reconnect(CurTick); if( g_pLogConnection ) g_pLogConnection->Reconnect( CurTick ); #if defined(_KRAZ) if (g_pActozShield) g_pActozShield->RepeatCheckerResult(CurTick); #endif // #if defined(_KRAZ) pIocp->DoUpdate( CurTick ); Sleep(1000); } return 0; } void CDNIocpManager::DoUpdate( UINT uiCurTick ) { if( uiCurTick-m_uiLastUpdateTick >= DNProcessCheck::UpdateInterval ) { CSocketContext* pSocketContext = reinterpret_cast(DNProcessCheck::Key); m_uiLastUpdateTick = timeGetTime(); for( UINT i=0 ; iLock(); m_vSpinBuffer[i]->RawPush( &pSocketContext, sizeof(CSocketContext*) ); m_vSpinBuffer[i]->RawPush( &uiCurTick, sizeof(uiCurTick) ); m_vSpinBuffer[i]->UnLock(); } } } #if defined(PRE_ADD_HEARTBEAT_TO_SQL) if (m_nLastHearbeatTick + DNProcessCheck::SQLHeartbeatInterval < uiCurTick ) { m_nLastHearbeatTick = timeGetTime(); CSocketContext* pSocketContext = reinterpret_cast(DNProcessCheck::HeartbeatKey); for( UINT i=0 ; iLock(); m_vSpinBuffer[i]->RawPush( &pSocketContext, sizeof(CSocketContext*) ); m_vSpinBuffer[i]->UnLock(); } } } #endif } void CDNIocpManager::OnAccept(CSocketContext *pSocketContext, const char* pIp, const int nPort) { g_Log.Log(LogType::_NORMAL, L"[OnAccept:%d] Socket:%d, Ip:%S, Port:%d\r\n", pSocketContext->m_dwKeyParam, pSocketContext->m_Socket, pIp, nPort); switch(pSocketContext->m_dwKeyParam) { case CONNECTIONKEY_DEFAULT: { CDNConnection *pCon = new CDNConnection; if (!pCon) return; pCon->SetIp(pIp); pCon->SetPort(nPort); pCon->SetServerConnection(true); pCon->SetSocketContext(this, pSocketContext); pSocketContext->SetParam(pCon); g_Log.Log(LogType::_NORMAL, L"[OnAccept] Socket:%d, Ip:%S\r\n", pSocketContext->m_Socket, pCon->GetIp()); } break; case CONNECTIONKEY_SERVICEMANAGER: { pSocketContext->SetParam(g_pServiceConnection); g_pServiceConnection->SetSocketContext(this, pSocketContext); g_pServiceConnection->SetServerConnection(false); g_Log.Log(LogType::_NORMAL, L"[OnAccept:Monitor] Socket:%d, Ip:%S\r\n", pSocketContext->m_Socket, g_pServiceConnection->GetIp()); } break; case CONNECTIONKEY_LOG: { pSocketContext->SetParam(g_pLogConnection); g_pLogConnection->SetSocketContext(this, pSocketContext); g_pLogConnection->SetServerConnection(false); g_Log.Log( LogType::_NORMAL, 0, 0, 0, 0, L"[OnAccept:Log] Socket:%d, Ip:%S\r\n", pSocketContext->m_Socket, g_pLogConnection->GetIp()); break; } } } void CDNIocpManager::OnConnectFail(CSocketContext *pSocketContext) { // ¼­¹ö¿¡¼­ Ä¿³ØÆ®¸¦ ½Ãµµ ÇÏ´Â ¾Öµé¸¸ ³Ö¾îÁÖ¼¼¿ä..AddConnectionEx¸¦ È£ÃâÇÏ´Â ¾Öµé? CConnection* pConnection = static_cast(pSocketContext->GetParam()); if( !pConnection ) return; pConnection->SetConnecting(false); switch(pSocketContext->m_dwKeyParam) { case CONNECTIONKEY_LOG: { // g_Log.Log(_ERROR, L"LogServer Fail(%S, %d)\r\n", pConnection->GetIp(), pConnection->GetPort()); // Àá±ñ ¸·¾ÆµÎ°ÚÀ½!!! 080918 saset } break; case CONNECTIONKEY_SERVICEMANAGER : { g_Log.Log(LogType::_ERROR, L"ServiceManager Connect Failed(%S, %d)\r\n", pConnection->GetIp(), pConnection->GetPort()); } break; } } void CDNIocpManager::OnConnected(CSocketContext *pSocketContext) { switch(pSocketContext->m_dwKeyParam) { case CONNECTIONKEY_DEFAULT: { CIocpManager::OnConnected(pSocketContext); CConnection *pCon = (CConnection*)pSocketContext->GetParam(); pCon->SetActive(true); pCon->SetDelete(false); g_Log.Log(LogType::_NORMAL, L"[OnConnected] Socket:%d, Ip:%S\r\n", pSocketContext->m_Socket, pCon->GetIp()); #if defined( PRE_FIX_67546 ) AddVillageGameConnection( (CDNConnection*)pCon ); TAAddThreadCount pA; memset(&pA, 0, sizeof(pA)); int nCount[THREADMAX]; GetConnectionCount( nCount ); memcpy( pA.nConnectionCount, nCount, sizeof(pA.nConnectionCount) ); ((CDNConnection*)(pCon))->AddSendData( MAINCMD_ETC, QUERY_ADD_CHANNELCOUNT, reinterpret_cast(&pA), sizeof(pA) ); #endif } break; case CONNECTIONKEY_SERVICEMANAGER: { g_pServiceConnection->SetActive(true); g_pServiceConnection->SetDelete(false); } break; case CONNECTIONKEY_LOG: { g_pLogConnection->SetActive(true); g_pLogConnection->SetDelete(false); } break; } } #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) #include #endif // #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) void CDNIocpManager::OnDisconnected(CSocketContext *pSocketContext) { switch(pSocketContext->m_dwKeyParam) { case CONNECTIONKEY_DEFAULT: { #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) DWORD dwTime = timeGetTime(); bool bDelete = false; bool bLog = true; #if defined( _WORK ) while( true ) #else while( timeGetTime()-dwTime <= 1000 ) #endif // #if defined( _WORK ) { CConnection *pCon = (CConnection*)pSocketContext->GetParam(); if( InterlockedCompareExchange( &pSocketContext->m_lActiveCount, CSocketContext::DeleteFlag, 0 ) == 0 ) { wstring strReason; pSocketContext->GetDetachReason(strReason); g_Log.Log(LogType::_ERROR, L"[%d] Disconnect Connection %s!!!\r\n", g_Config.nManagedID, strReason.c_str()); #if defined( PRE_FIX_67546 ) DelVillageGameConnection( (CDNConnection*)pCon ); #endif bDelete = true; pCon->SetSocketContext(NULL, NULL); SAFE_DELETE(pCon); ClearSocketContext(pSocketContext); #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) && defined( _WORK) std::cout << "»èÁ¦»èÁ¦¿À¿¹~~~~~" << std::endl; #endif // #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) && defined( _WORK) break; } else { if( bLog == true ) { wstring strReason; pSocketContext->GetDetachReason(strReason); g_Log.Log(LogType::_ERROR, L"[%d] DBServer Occur DanglingPointer %s!!!\r\n", g_Config.nManagedID, strReason.c_str()); bLog = false; } } } if( bDelete == false ) { g_Log.Log(LogType::_ERROR, L"[%d] DBServer DanglingPointer Delete Fail!!!\r\n", g_Config.nManagedID ); } #else CConnection *pCon = (CConnection*)pSocketContext->GetParam(); g_Log.Log(LogType::_NORMAL, L"[OnDisconnected] Socket:%d, Ip:%S\r\n", pSocketContext->m_Socket, pCon->GetIp()); pCon->SetActive(false); pCon->SetDelete(true); ClearSocketContext(pSocketContext); pCon->SetSocketContext(NULL, NULL); #if defined(_WORK) SAFE_DELETE(pCon); #endif // _WORK #endif // #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) } break; case CONNECTIONKEY_SERVICEMANAGER: { g_pServiceConnection->Disconnected(); g_pServiceConnection->SetActive(false); g_pServiceConnection->SetDelete(true); ClearSocketContext(pSocketContext); g_pServiceConnection->SetSocketContext(NULL, NULL); } break; case CONNECTIONKEY_LOG: { g_pLogConnection->SetActive(false); g_pLogConnection->SetDelete(true); ClearSocketContext(pSocketContext); g_pLogConnection->SetSocketContext(NULL, NULL); #if defined(PRE_ADD_LOGSERVER_HEARTBEAT) g_pLogConnection->ResetLiveCheck(); #endif } break; } } void CDNIocpManager::OnReceive(CSocketContext *pSocketContext, DWORD dwBytesTransferred) { #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) CScopeInterlocked Scope( &pSocketContext->m_lActiveCount ); if( Scope.bIsDelete() ) return; #endif // #if defined( PRE_FIX_SOCKETCONTEXT_DANGLINGPTR ) CConnection* pCon = (CConnection*)pSocketContext->GetParam(); if( pSocketContext->m_dwKeyParam == CONNECTIONKEY_SERVICEMANAGER || pSocketContext->m_dwKeyParam == CONNECTIONKEY_LOG ) { if (pCon) { int iRet = pCon->AddRecvData( pSocketContext ); if( iRet > 0 ) { pCon->FlushRecvData(0); } } return; } int iPushCount = 0; const char* pRecvBuffer = pSocketContext->m_RecvIO.buffer; UINT uiRecvBufferLen = pSocketContext->m_RecvIO.Len; DN_ASSERT( m_vCallEvent.size() == m_vSpinBuffer.size(), "m_vCallEvent.size() == m_vSpinBuffer.size()" ); std::vector vCallEvent; vCallEvent.reserve( m_vSpinBuffer.size() ); vCallEvent.assign( m_vSpinBuffer.size(), 0 ); while( uiRecvBufferLen ) { static CTcpRecvSpinBuffer sTcpSpinBuffer(1,0); UINT uiPacketLen = 0; uiPacketLen = sTcpSpinBuffer.GetCompletePacketLength( pRecvBuffer, uiRecvBufferLen ); if( uiPacketLen <= 0 ) break; const DNTPacket* pPacket = reinterpret_cast(pRecvBuffer); DN_ASSERT( pPacket->iLen > 0, "pPacket->iLen" ); BYTE cThreadID; memcpy( &cThreadID, pPacket->buf, sizeof(BYTE) ); DN_ASSERT( cThreadID < m_vSpinBuffer.size(), "cThread < m_vSpinBuffer.size()" ); if( cThreadID < m_vSpinBuffer.size() ) { m_vSpinBuffer[cThreadID]->Lock(); int iRet = m_vSpinBuffer[cThreadID]->RawPush( &pSocketContext, sizeof(CSocketContext*) ); DN_ASSERT( iRet == 0, "m_vSpinBuffer[cThreadID]->RawPush() 1" ); iRet = m_vSpinBuffer[cThreadID]->RawPush( pRecvBuffer, uiPacketLen ); DN_ASSERT( iRet == 0, "m_vSpinBuffer[cThreadID]->RawPush() 2" ); m_vSpinBuffer[cThreadID]->UnLock(); } else { CConnection* pCon = static_cast(pSocketContext->GetParam()); g_Log.Log( LogType::_ERROR, L"DB ThreadID Error!!! MainCmd:%d SubCmd:%d ThreadID:%d/%d ConKeyParam=%d PacketLen=%d RemainBufLen=%d IP=%s\r\n", (int)pPacket->cMainCmd, (int)pPacket->cSubCmd, (int)cThreadID, m_vSpinBuffer.size(), pSocketContext->m_dwKeyParam, uiPacketLen, uiRecvBufferLen, pCon?pCon->GetwszIp():L"NULL" ); pRecvBuffer += uiPacketLen; uiRecvBufferLen -= uiPacketLen; continue; } pRecvBuffer += uiPacketLen; uiRecvBufferLen -= uiPacketLen; ++iPushCount; InterlockedExchangeAdd( &(static_cast(pCon)->m_lDBQueueRemainSize), uiPacketLen ); vCallEvent[cThreadID] = true; } if( iPushCount > 0 ) { pSocketContext->m_RecvIO.Len = uiRecvBufferLen; if( uiRecvBufferLen ) memmove( &pSocketContext->m_RecvIO.buffer, pRecvBuffer, uiRecvBufferLen ); } } int CDNIocpManager::CreateThread() { HANDLE hThread; UINT ThreadID; hThread = (HANDLE)_beginthreadex(NULL, 0, &ReconnectThread, this, 0, &ThreadID); if (hThread == INVALID_HANDLE_VALUE) return -1; CloseHandle(hThread); return 0; } CSpinBuffer* CDNIocpManager::GetSpinBuffer( UINT uiIndex ) { DN_ASSERT( m_vSpinBuffer.size() > uiIndex, "m_vSpinBuffer.size() > uiIndex" ); return m_vSpinBuffer[uiIndex]; } #if defined( PRE_FIX_67546 ) void CDNIocpManager::AddVillageGameConnection( CDNConnection* pCon ) { m_vVillageGameConnection.push_back(pCon); } void CDNIocpManager::DelVillageGameConnection( CDNConnection* pCon ) { for(std::vector::iterator itor = m_vVillageGameConnection.begin();itor != m_vVillageGameConnection.end();itor++ ) { if( *itor == pCon ) { m_vVillageGameConnection.erase(itor); break; } } } CDNConnection* CDNIocpManager::GetVillageGameConnection( int nIndex ) { if( nIndex >= m_vVillageGameConnection.size() ) return NULL; return m_vVillageGameConnection[nIndex]; } void CDNIocpManager::AddConnectionCount( int nIndex ) { if( nIndex >= THREADMAX ) return; m_nConnectionCount[nIndex]++; } void CDNIocpManager::GetConnectionCount( int *ConnectionCount ) { for( int i=0;i