Files
mir_server/server/GateServer/DataProcess.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

2151 lines
59 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "DataProcess.h"
#include "SockProcess.h"
HANDLE g_hStdOut;
unsigned int CRunDataProcesser::s_nSndThreadSleepTime = 20;
extern bool g_ServerIsRunning;
//接收数据的线程
#ifdef _MSC_VER
VOID STDCALL CRunDataProcesser::RecvDataProcdaessRoutine(void *arg)
#else
VOID* CRunDataProcesser::RecvDataProcessRoutine(void *arg)
#endif
{
CRunDataProcesser * pRunData = (CRunDataProcesser *)arg;
//LPCRITICAL_SECTION pQueueLock;
CBaseList<LPVOID> *pRecvList;
PCLIENTRECVBUF *ppRecvBufs, pRecvBuf;
PRUNGATEUSERSESSION pSession;
INT_PTR nBufferCount;
TICKCOUNT dwProcStartTick, dwLockDataTick, dwLockCheckTick, dwSendCheckTick, dwPerfDumpTick, dwSendGateUserInfo;
//pQueueLock = &pRunData->m_RecvQueueLock;
pRecvList = pRunData->m_pRecvProcList;
pRunData->m_llSendKeepAliveTime = 0;
dwLockDataTick = dwLockCheckTick = dwPerfDumpTick = dwSendGateUserInfo = _getTickCount();
dwSendCheckTick = dwSendGateUserInfo + 2000;
while ( !pRunData->m_boStoping )
{
dwProcStartTick = _getTickCount();
//发送网关自检
if ( dwProcStartTick - dwSendCheckTick >= 2000 )
{
pRunData->SendCheck( GM_CHECKSERVER );
dwSendCheckTick = dwProcStartTick;
pRunData->m_llSendKeepAliveTime = dwSendCheckTick;
}
// 发送网关用户数目,一分钟发一次
if (dwProcStartTick - dwSendGateUserInfo >= 60000 )
{
pRunData->SendGateUserInfo();
dwSendGateUserInfo = dwProcStartTick;
}
//检查会话关闭
if ( dwProcStartTick - dwLockCheckTick >= 5000 )
{
if ( pRunData->CheckCloseSessions( dwProcStartTick - dwLockCheckTick >= 10000 ) )
{
dwProcStartTick = dwLockCheckTick = _getTickCount();
}
}
// dump statistic
if (dwProcStartTick - dwPerfDumpTick >= 120000)
{
CTimeProfMgr::getSingleton().dump();
dwPerfDumpTick = dwProcStartTick;
}
//如果未能获得数据队列锁则让出本次CPU时间
if ( !TryEnterCriticalSection( &pRunData->m_RecvQueueLock ) )
{
if ( dwProcStartTick - dwLockDataTick < 60 )
{
Sleep( 1 );
continue;
}
else
{
EnterCriticalSection( &pRunData->m_RecvQueueLock );
dwProcStartTick = dwLockDataTick = _getTickCount();
}
}
else dwLockDataTick = dwProcStartTick;
//交换数据处理队列
pRecvList = pRunData->m_pRecvAppendList;
pRunData->m_pRecvAppendList = pRunData->m_pRecvProcList;
pRunData->m_pRecvProcList = pRecvList;
LeaveCriticalSection( &pRunData->m_RecvQueueLock );
//如果没有待处理的数据则让出本次CPU时间
nBufferCount = pRecvList->count();
if ( !nBufferCount )
{
Sleep( 1 );
continue;
}
ppRecvBufs = (PCLIENTRECVBUF*)(void**)(*pRecvList);
while ( nBufferCount > 0 )
{
pRecvBuf = *ppRecvBufs;
nBufferCount--;
ppRecvBufs++;
pSession = pRecvBuf->pSession;
if ( pRecvBuf->nBufferSize > 0 )
{
//如果会话被关闭或效验过期则不予处理
if ( pSession->nSocket != INVALID_SOCKET && pSession->nVerifyIdx == pRecvBuf->nVerify && !pSession->boMarkToClose && !pSession->boRemoteClosed )
{
pSession->dwClientMsgTick = dwProcStartTick;
//OutputMsg( rmTip, "dwProcStartTick=%I64d",dwProcStartTick);
pRunData->ProcessUserRecvPacket( pSession, (char*)(pRecvBuf + 1), pRecvBuf->nBufferSize );
pSession->nRecvPacketCount++;
}
}
free( pRecvBuf );
}
pRecvList->clear();
pRunData->m_dwLastProcUsrMsgTime = _getTickCount() - dwProcStartTick;
//循环小于指定时间则休眠一次
//if ( pRunData->m_dwLastProcUsrMsgTime < 16 )
if(TRUE)
{
Sleep ( 1 );
}
}
ExitThread( 0 );
}
//发送数据的线程
#ifdef _MSC_VER
VOID STDCALL CRunDataProcesser::SendDataProcessRoutine(void* arg)
#else
VOID* CRunDataProcesser::SendDataProcessRoutine(void* arg)
#endif
{
PRUNDATASENDTHREAD pRunThread = (PRUNDATASENDTHREAD)arg;
TICKCOUNT dwProcStartTick;
CRunDataProcesser *pRunData;
int nLockSendBufQLockFail = 0;
pRunData = pRunThread->pRunData;
while ( !pRunData->m_boStoping )
{
dwProcStartTick = _getTickCount();
if ( pRunData->CopyWaitSendBuffers( pRunThread, TRUE) )
nLockSendBufQLockFail = 0;
else nLockSendBufQLockFail ++;
pRunData->CheckSendSessionBuffers( pRunThread );
//循环小于指定时间则休眠一次
pRunThread->dwProcTick = _getTickCount() - dwProcStartTick;
//if ( pRunThread->dwProcTick < 20 )
{
dwProcStartTick = _getTickCount();
Sleep(s_nSndThreadSleepTime);
TICKCOUNT curTick = _getTickCount();
pRunThread->dwSleepTick = curTick - dwProcStartTick;
}
/*else
pRunThread->dwSleepTick = 0;*/
}
ExitThread( 0 );
}
//收到了服务器的数据,进行处理
//VOID CRunDataProcesser::ProcessRecvBuffers(const GateMsg* msg)
VOID CRunDataProcesser::ProcessRecvBuffers(const GATEMSGHDR* pHeader, LPCSTR pData, size_t nLen)
{
Assert(pHeader->dwGateCode == RUNGATECODE);
/*if (msg->header.wIdent == GM_DATA)
Assert(msg->header.wTemp == RUNTEMPCODE);*/
if (s_nIgnoreDataPacket)
return;
//如果是关闭服务器的话
if(pHeader->wIdent ==GM_CLOSE_SERVER)
{
OutputMsg(rmTip,"Back server close from back");
g_ServerIsRunning = false;
return;
}
else if (pHeader->wIdent == GM_APPBIGPACK)
{
char* pBuffEnd = (char *)pData + nLen;
GATEMSGHDR* pCurHeader = (GATEMSGHDR *)pData;
while ((char*)pCurHeader < pBuffEnd)
{
if (pCurHeader->dwGateCode != RUNGATECODE)
{
OutputMsg(rmError, _T("%s recv packet invalid..."), __FUNCTION__);
break;
}
DispathRecvMessage(pCurHeader, (const char*)(pCurHeader+1), pCurHeader->nDataSize);
pCurHeader = (GATEMSGHDR *)((char *)pCurHeader + (sizeof(GATEMSGHDR) + pCurHeader->nDataSize));
}
}
else
DispathRecvMessage((GATEMSGHDR * const)pHeader, pData, nLen);
}
VOID CRunDataProcesser::DispathRecvMessage(const PGATEMSGHDR pMsgHdr, const char *pBuffer, SIZE_T nBufSize)
{
PRUNGATEUSERSESSION pSession;
/*
if(GM_DATA ==pMsgHdr->wIdent)
{
OutputMsg(rmTip, _T("收到后台数据,cmd=%d,wSessionIdx=%d,wServerIdx=%d,socket=%d\n"),
pMsgHdr->wIdent, pMsgHdr->wSessionIdx,pMsgHdr->wServerIdx,pMsgHdr->nSocket);
}
*/
switch ( pMsgHdr->wIdent )
{
case GM_CLOSE:
if ( pMsgHdr->wSessionIdx < m_nMaxSessionCount )
{
pSession = &m_Sessions[pMsgHdr->wSessionIdx];
if ( pSession->nSocket == pMsgHdr->nSocket && !pSession->boMarkToClose && !pSession->boRemoteClosed )
{
SendCloseSession( pSession, FALSE, enReasonGM );
}
else
{
OutputMsg( rmWaning, _T("GM_CLOSE socket不匹配 wSessionIdx=%d,本地Socket=%d,后台的为%d"),
pMsgHdr->wSessionIdx, pSession->nSocket, pMsgHdr->nSocket );
}
}
break;
case GM_CHECKCLIENT:
{
// 保存服务器的时间
if (m_llSendKeepAliveTime > 0)
{
if (m_nCheckTimeCount < 10)
{
TICKCOUNT nTimeDiff = pMsgHdr->tickCount - _getTickCount();
m_llOccuTimeDiff += nTimeDiff;
m_nCheckTimeCount++;
m_llSvrTimeDiff = (long long)(m_llOccuTimeDiff / (float)m_nCheckTimeCount);
OutputMsg(rmNormal, _T("timediff=%lld,result dif=%lld,checkTimecount=%d"),
nTimeDiff,
m_llSvrTimeDiff,
m_nCheckTimeCount);
}
}
/*OutputMsg(rmNormal, _T("------logicSvrTime=%I64d gateTime=%I64d, timeDif=%I64d"), pMsgHdr->tickCount, nCurrTick, m_llSvrTimeDiff);*/
}
break;
case GM_APPKEEPALIVE:
{
// 给服务器会应答消息
pSession = &m_Sessions[pMsgHdr->wSessionIdx];
if ( pSession->nSocket == pMsgHdr->nSocket && !pSession->boMarkToClose && !pSession->boRemoteClosed )
{
SendKeepAliveAck( pSession, pBuffer, nBufSize);
}
break;
}
case GM_SERVERUSERINDEX:
if ( pMsgHdr->wSessionIdx < m_nMaxSessionCount )
{
pSession = &m_Sessions[pMsgHdr->wSessionIdx];
if ( pSession->nSocket == pMsgHdr->nSocket && !pSession->boMarkToClose && !pSession->boRemoteClosed )
{
pSession->nServerIdx = pMsgHdr->wServerIdx;
OutputMsg(rmNormal, _T("recv GM_ServerIndex msg. socket=%d, sessionId=%d, set serverIdx=%d"),
(int)pSession->nSocket, (int)pSession->nIndex, pSession->nServerIdx);
}
else
{
OutputMsg(rmError, _T("GM_ServerIndex Error, session closed or socket unmatch(session socket=%d, sessionId=%d, msghdr socket=%d"),
(int)pSession->nSocket, (int)pSession->nIndex, (int)pMsgHdr->nSocket);
}
}
break;
case GM_DATA:
if ( pMsgHdr->wSessionIdx < m_nMaxSessionCount )
{
pSession = &m_Sessions[pMsgHdr->wSessionIdx];
if ( !pSession->boMarkToClose && !pSession->boRemoteClosed )
{
if ( pSession->nSocket == pMsgHdr->nSocket )
{
PostUserServerData( pSession, pBuffer, (INT)nBufSize, TRUE, TRUE, (TICKCOUNT)pMsgHdr->tickCount);
}
else
{
OutputMsg( rmWaning, "GM_DATA 会话(%d:%s)套接字不匹配data Socket=%d,local socket=%d", pMsgHdr->wSessionIdx, pSession->sLoginCharName, pMsgHdr->nSocket,pSession->nSocket );
//SendCloseSession((SOCKET)pMsgHdr->nSocket); //如果套接字不匹配
//SendCloseSession( pSession, TRUE, enReasonAllSessionClose );
}
}
else
{
OutputMsg( rmWaning, "GM_DATA 会话(%d:%s,%d,%d)已关闭", pMsgHdr->wSessionIdx, pSession->sLoginCharName,
(int)(pSession->boMarkToClose),(int)(pSession->boRemoteClosed));
//这种情况下再次向逻辑发送关闭连接
//SendCloseSession((SOCKET)pMsgHdr->nSocket);
}
}
else OutputMsg( rmWaning, "GM_DATA 会话ID无效(%d)", pMsgHdr->wSessionIdx );
break;
default:
{
GotError( __FUNCTION__, _T("无效的消息序列"), pMsgHdr->wIdent );
}
break;
}
}
VOID CRunDataProcesser::OnConnected()
{
Inherited::OnConnected();
m_llSendKeepAliveTime = 0;
m_nCheckTimeCount = 0;
m_llOccuTimeDiff = 0;
OutputMsg(rmTip, _T("BackServer Connected"));
}
VOID CRunDataProcesser::OnClosed()
{
Inherited::OnClosed();
CloseAllSessions(true);
}
VOID CRunDataProcesser::OnError(int errorCode)
{
OutputError(errorCode, _T("BackServer Socket Error "));
}
VOID CRunDataProcesser::OnDisconnected()
{
m_llSvrTimeDiff = 0;
m_nCheckTimeCount = 0;
m_llOccuTimeDiff = 0;
OutputMsg(rmWaning, _T("BackServer Connection Closed"));
}
CRunDataProcesser::CRunDataProcesser(const int nMaxSessionCount)
:Inherited()
{
m_nActiveUser = 0;
m_boStoping = FALSE;
m_boStarted = FALSE;
m_DataProcessType = dp_Default;
/*
m_hPipe = INVALID_HANDLE_VALUE;
strcpy( m_sPipeName, "\\\\.\\pipe\\default" );
sprintf( m_sGateName, "游戏网关%d", _getTickCount() % 100 );
*/
m_hProcRecvThread = NULL;
ZeroMemory( m_SendThreads, sizeof(m_SendThreads) );
m_nSendThreadCount = 2;
m_nMaxSessionCount = nMaxSessionCount; // 默认值: 16384
m_Sessions = NULL;
m_pSockProcesser = NULL;
InitializeCriticalSection( &m_SessionLock );
if ( m_Sessions ) ZeroMemory( m_Sessions, sizeof(m_Sessions) );
InitializeCriticalSection( &m_RecvQueueLock );
m_pRecvAppendList = &m_RecvQueue[0];
m_pRecvProcList = &m_RecvQueue[1];
m_ServerBuf.lpBuffer= NULL;
m_ServerBuf.nSize = 0;
m_ServerBuf.nOffset = 0;
m_nUserVerify = 1;
m_dwProcessRecvSize = 0;
m_boPrintC2SMsg = FALSE;
m_boPrintS2CMsg = FALSE;
m_llSvrTimeDiff = 0;
m_nCheckTimeCount = 0;
m_llOccuTimeDiff = 0;
InitSendThreadData();
//m_DataPacker.SetNeedEncrypt(true); //需要加密
}
CRunDataProcesser::~CRunDataProcesser()
{
Stop();
UninitSendThreadData();
DeleteCriticalSection( &m_RecvQueueLock );
DeleteCriticalSection( &m_SessionLock );
}
VOID CRunDataProcesser::InitSessions()
{
int i;
PRUNGATEUSERSESSION pSession;
EnterCriticalSection( &m_SessionLock );
if ( !m_Sessions )
{
m_Sessions = (PRUNGATEUSERSESSION)malloc(sizeof(m_Sessions[0]) * m_nMaxSessionCount);
ZeroMemory( m_Sessions, sizeof(m_Sessions[0]) * m_nMaxSessionCount );
}
pSession = m_Sessions;
for ( i=0; i<m_nMaxSessionCount; ++i )
{
pSession->nIndex = i;
pSession->nSocket = INVALID_SOCKET;
#ifdef WIN32
pSession->Overlapped.pUser = pSession;
#endif
pSession->nServerIdx = 0;
pSession->btPacketIdx = 0;
pSession->wPacketError = 0;
pSession->nRecvPacketCount = 0;
pSession->nSendPacketCount = 0;
pSession->boMarkToClose = false;
pSession->boRemoteClosed = false;
pSession->boSendAvaliable = true;
INIT_SESSION_SEND( pSession );
pSession++;
}
LeaveCriticalSection( &m_SessionLock );
}
VOID CRunDataProcesser::UninitSessions()
{
int i;
PRUNGATEUSERSESSION pSession;
if ( !m_Sessions ) return;
EnterCriticalSection( &m_SessionLock );
pSession = m_Sessions;
for ( i=0; i<m_nMaxSessionCount; ++i )
{
if ( pSession->RecvBuf.lpBuffer )
{
free( pSession->RecvBuf.lpBuffer );
pSession->RecvBuf.lpBuffer = NULL;
pSession->RecvBuf.nSize = pSession->RecvBuf.nOffset = 0;
}
if ( pSession->SendBuf.lpBuffer )
{
free( pSession->SendBuf.lpBuffer );
pSession->SendBuf.lpBuffer = NULL;
pSession->SendBuf.nSize = pSession->SendBuf.nOffset = 0;
}
UNINIT_SESSION_SEND( pSession );
pSession++;
}
free( m_Sessions );
m_Sessions = NULL;
LeaveCriticalSection( &m_SessionLock );
}
VOID CRunDataProcesser::FreeRecvBuffers()
{
INT_PTR i;
void **pBuffers;
EnterCriticalSection( &m_RecvQueueLock );
pBuffers = *m_pRecvAppendList;
for ( i=m_pRecvAppendList->count()-1; i>-1; --i )
{
free( pBuffers[i] );
}
m_pRecvAppendList->clear();
pBuffers = *m_pRecvProcList;
for ( i=m_pRecvProcList->count()-1; i>-1; --i )
{
free( pBuffers[i] );
}
m_pRecvProcList->clear();
LeaveCriticalSection( &m_RecvQueueLock );
}
VOID CRunDataProcesser::FreeSendBuffers(PRUNDATASENDTHREAD pSendThread)
{
INT_PTR i;
void **pBuffers;
EnterCriticalSection( &pSendThread->SendQueueLock );
pBuffers = *pSendThread->pSendAppendList;
for ( i=pSendThread->pSendAppendList->count()-1; i>-1; --i )
{
free( pBuffers[i] );
}
pSendThread->pSendAppendList->clear();
pBuffers = *pSendThread->pSendProcList;
for ( i=pSendThread->pSendProcList->count()-1; i>-1; --i )
{
free( pBuffers[i] );
}
pSendThread->pSendProcList->clear();
LeaveCriticalSection( &pSendThread->SendQueueLock );
}
/*
BOOL CRunDataProcesser::OpenServerPipe()
{
int nErr;
while ( TRUE )
{
m_hPipe = CreateFile( m_sPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL );
if ( m_hPipe != INVALID_HANDLE_VALUE )
return TRUE;
nErr = GetLastError();
if ( nErr != ERROR_PIPE_BUSY )
{
GotError( __FUNCTION__, "CreateFile", nErr );
break;
}
if ( !WaitNamedPipe( m_sPipeName, 10000 ) )
{
nErr = GetLastError();
GotError( __FUNCTION__, "WaitNamedPipe", nErr );
break;
}
}
return FALSE;
}
VOID CRunDataProcesser::CloseServerPipe()
{
if ( m_hPipe != INVALID_HANDLE_VALUE )
{
CloseHandle( m_hPipe );
m_hPipe = INVALID_HANDLE_VALUE;
}
}
VOID CRunDataProcesser::ServerPipeError()
{
if ( m_hPipe != INVALID_HANDLE_VALUE )
{
CancelRemainSendSessionBuffers();
CloseHandle( m_hPipe );
m_hPipe = INVALID_HANDLE_VALUE;
//CloseAllSessions 必须在CloseHandle之后调用否则CloseAllSessions->SendServerMessage->ServerPipeError 造成栈溢出
CloseAllSessions( TRUE );
}
}
*/
BOOL CRunDataProcesser::CopyWaitSendBuffers(PRUNDATASENDTHREAD pSendThread, BOOL boForceCopy)
{
PSENDCLIENTBUF pSendBuf, *ppBufers;
CBaseList<LPVOID> *pBufferList;
PRUNGATEUSERSESSION pSession;
INT_PTR nCount, nSize, nTotalSize, nAppendSize;
TICKCOUNT dwMsgTick;
if ( !boForceCopy )
boForceCopy = TryEnterCriticalSection( &pSendThread->SendQueueLock );
else EnterCriticalSection( &pSendThread->SendQueueLock );
if ( boForceCopy )
{
pBufferList = pSendThread->pSendAppendList;
pSendThread->pSendAppendList = pSendThread->pSendProcList;
pSendThread->pSendProcList = pBufferList;
LeaveCriticalSection( &pSendThread->SendQueueLock );
nCount = pBufferList->count();
if ( nCount > 0 )
{
dwMsgTick = _getTickCount();
ppBufers = (PSENDCLIENTBUF*)(void**)(*pBufferList);
nTotalSize = 0;
nAppendSize = 0;
do
{
pSendBuf = *ppBufers;
ppBufers++;
nCount--;
pSession = pSendBuf->pSession;
if ( pSession->nSocket != INVALID_SOCKET && !pSession->boMarkToClose && !pSession->boRemoteClosed )
{
nSize = pSession->SendBuf.nOffset + pSendBuf->nBufferSize + 1;
if ( pSession->SendBuf.nSize < nSize )
{
nSize = (nSize / SESSION_DATAGROW_SIZE + 1) * SESSION_DATAGROW_SIZE;
pSession->SendBuf.nSize = (INT)nSize;
pSession->SendBuf.lpBuffer = (char*)realloc( pSession->SendBuf.lpBuffer, nSize );
}
memcpy( &pSession->SendBuf.lpBuffer[pSession->SendBuf.nOffset], pSendBuf + 1, pSendBuf->nBufferSize );
pSession->SendBuf.nOffset += pSendBuf->nBufferSize;
pSession->SendBuf.lpBuffer[pSession->SendBuf.nOffset] = 0;
pSession->dwServerMsgTick = dwMsgTick;
nAppendSize += pSendBuf->nBufferSize;
}
nTotalSize += pSendBuf->nBufferSize;
free( pSendBuf );
}
while ( nCount > 0 );
pBufferList->clear();
// 原子操作
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, (LONG)nAppendSize );
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendQueueSize, -(INT)nTotalSize );
}
}
return boForceCopy;
}
VOID CRunDataProcesser::GetSessionLoginInfo(PRUNGATEUSERSESSION pSession, char *sBuffer, int nBufferSize)
{
}
VOID CRunDataProcesser::GotError(LPCSTR sErrFn, LPCSTR sErrApi, int nErr)
{
OutputMsg( rmError, _T("CRunDataProcesser::%s Got Error %d on api \"%s\""), sErrFn, nErr, sErrApi );
}
VOID CRunDataProcesser::InitSendThreadData()
{
int i;
for ( i=0; i<m_nSendThreadCount; ++i )
{
InitializeCriticalSection( &m_SendThreads[i].SendQueueLock );
m_SendThreads[i].pRunData = this;
m_SendThreads[i].nThreadIdx = i;
m_SendThreads[i].boSendEWouldBlock = false;
m_SendThreads[i].boSendFewBuffer = false;
m_SendThreads[i].pSendAppendList = new CBaseList<LPVOID>();
m_SendThreads[i].pSendProcList = new CBaseList<LPVOID>();
}
}
VOID CRunDataProcesser::UninitSendThreadData()
{
int i;
for ( i=0; i<m_nSendThreadCount; ++i )
{
SafeDelete( m_SendThreads[i].pSendAppendList );
SafeDelete( m_SendThreads[i].pSendProcList );
DeleteCriticalSection( &m_SendThreads[i].SendQueueLock );
}
}
VOID CRunDataProcesser::SendCheck(int nIdent)
{
SendServerMessage( nIdent, 0, 0, 0, m_sGateName, (int)strlen(m_sGateName) + 1 );
}
VOID CRunDataProcesser::SendGateUserInfo()
{
GATEUSERINFO gi;
gi.nUserCount = GetActiveUserCount();
gi.nGatePort = GetRunSockProcesser()->GetBindPort();
SendServerMessage(GM_GATEUSERINFO, 0, 0, 0, (char *)&gi, sizeof(GATEUSERINFO));
}
VOID CRunDataProcesser::SendOpenSession(PRUNGATEUSERSESSION pSession)
{
char sRemoteAddr[32];
strcpy( sRemoteAddr, inet_ntoa( pSession->SockAddr.sin_addr ) );
SendServerMessage( GM_OPEN, pSession->nIndex, pSession->nSocket, 0, sRemoteAddr, (int)strlen(sRemoteAddr) + 1 );
OutputMsg(rmTip, _T("SendOpenSession: socket=%d sessionId=%d, remoteAddr=%s"), (int)pSession->nSocket, (int)pSession->nIndex, sRemoteAddr);
}
VOID CRunDataProcesser::SendCloseSession(PRUNGATEUSERSESSION pSession, BOOL boCloseOnServer, INT nReason)
{
PCLIENTRECVBUF pRecvBuf;
int nSocket;
if ( !pSession->boMarkToClose && pSession->nSocket != INVALID_SOCKET )
{
OutputMsg( rmWaning, "关闭会话 socket=%d, sessionId=%d, serverId=%d,reasonId=%d,nVerifyIdx=%ld", (int)pSession->nSocket,
(int)pSession->nIndex, (int)pSession->nServerIdx, nReason, pSession->nVerifyIdx );
pSession->boMarkToClose = true;
nSocket = (int)pSession->nSocket;
pSession->nSocket = INVALID_SOCKET;
pSession->dwCloseTick = _getTickCount();
pSession->nVerifyIdx = 0;
bool isInCommu =( pSession->nSessionSatus == enCommunication); //当前是否在通信状态
pSession->nSessionSatus = enSessionStatusIdle; //初始化状态
if (nSocket!=INVALID_SOCKET) closesocket( nSocket );
//如果需要向服务器发送关闭用户的消息则将消息添加到队列
//并且需要通信状态了,否则不需要发包,说明还没有通过验证
if ( boCloseOnServer && isInCommu )
{
SendServerMessage( GM_CLOSE, 0, nSocket, 0, NULL, 0 );
}
m_nActiveUser--;
}
}
VOID CRunDataProcesser::SendKeepAliveAck(PRUNGATEUSERSESSION pSession, const char *pBuffer, SIZE_T nBufSize)
{
SendServerMessage(GM_APPKEEPALIVEACK, pSession->nIndex, pSession->nSocket, pSession->nServerIdx, (char *)pBuffer, (int)nBufSize);
}
VOID CRunDataProcesser::CloseAllSessions(BOOL boForceClose)
{
int i;
TICKCOUNT dwCurTick;
PRUNGATEUSERSESSION pSession;
if ( !m_Sessions ) return;
pSession = m_Sessions;
EnterCriticalSection( &m_SessionLock );
EnterCriticalSection( &m_RecvQueueLock );
for ( i=0; i<m_nSendThreadCount; ++i )
{
EnterCriticalSection( &m_SendThreads[i].SendQueueLock );
}
Sleep( 3000 );//休眠以等待数据接收以及各发送线程被阻塞
dwCurTick = _getTickCount();
for ( i=0; i<m_nMaxSessionCount; ++i )
{
if ( pSession->nSocket != INVALID_SOCKET )
{
if ( boForceClose )
{
OutputMsg(rmTip,_T("CRunDataProcesser::CloseAllSessions close socket=%d"),(int)pSession->nSocket);
SendCloseSession( pSession, TRUE, enReasonAllSessionClose );
//closesocket( pSession->nSocket );
pSession->boMarkToClose = true;
pSession->boRemoteClosed = true;
pSession->dwCloseTick = 0;
pSession->nSocket = INVALID_SOCKET;
pSession->nVerifyIdx = 0;
m_nActiveUser--;
if ( pSession->RecvBuf.lpBuffer )
{
free( pSession->RecvBuf.lpBuffer );
pSession->RecvBuf.lpBuffer = NULL;
}
pSession->RecvBuf.nSize = pSession->RecvBuf.nOffset = 0;
if ( pSession->SendBuf.lpBuffer )
{
free( pSession->SendBuf.lpBuffer );
pSession->SendBuf.lpBuffer = NULL;
}
pSession->SendBuf.nSize = pSession->SendBuf.nOffset = 0;
}
else SendCloseSession( pSession, TRUE, enReasonAllSessionClose );
}
pSession++;
}
for ( i=0; i<m_nSendThreadCount; ++i )
{
LeaveCriticalSection( &m_SendThreads[i].SendQueueLock );
}
LeaveCriticalSection( &m_RecvQueueLock );
LeaveCriticalSection( &m_SessionLock );
}
VOID CRunDataProcesser::CancelRemainSendSessionBuffers()
{
PSENDCLIENTBUF pSendBuf, *ppBufers;
CBaseList<LPVOID> *pBufferList;
INT_PTR i, nCount, nTotalSize;
nTotalSize = 0;
for ( i=0; i<m_nSendThreadCount; ++i )
{
EnterCriticalSection( &m_SendThreads[i].SendQueueLock );
pBufferList = m_SendThreads[i].pSendProcList;
nCount = pBufferList->count();
if ( nCount )
{
ppBufers = (PSENDCLIENTBUF*)(void**)(*pBufferList);
do
{
pSendBuf = *ppBufers;
ppBufers++;
nCount--;
nTotalSize += pSendBuf->nBufferSize;
free( pSendBuf );
}
while ( nCount > 0 );
pBufferList->clear();
}
pBufferList = m_SendThreads[i].pSendAppendList;
nCount = pBufferList->count();
if ( nCount )
{
ppBufers = (PSENDCLIENTBUF*)(void**)(*pBufferList);
do
{
pSendBuf = *ppBufers;
ppBufers++;
nCount--;
nTotalSize += pSendBuf->nBufferSize;
free( pSendBuf );
}
while ( nCount > 0 );
pBufferList->clear();
}
LeaveCriticalSection( &m_SendThreads[i].SendQueueLock );
}
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendQueueSize, -(INT)nTotalSize );
}
BOOL CRunDataProcesser::CheckCloseSessions(BOOL boForceCheck)
{
static const DWORD dwCloseIdleSessionLong = 10 * 60 * 1000;
int i, boResult;
TICKCOUNT dwCurTick;
PRUNGATEUSERSESSION pSession;
if ( boForceCheck )
{
EnterCriticalSection( &m_SessionLock );
boResult = TRUE;
}
else boResult = TryEnterCriticalSection( &m_SessionLock );
if ( boResult )
{
dwCurTick = _getTickCount();
pSession = m_Sessions - 1;
for ( i=0; i<m_nMaxSessionCount; ++i )
{
pSession++;
if ( pSession->boMarkToClose || pSession->boRemoteClosed )
{
//加上pSession->dwCloseTick非0判断防止内存错误
//可能的原因是标记pSession->boMarkToClose或pSession->boRemoteClosed为true的线程尚未来得及
//给pSession->dwCloseTick赋值而此线程恰好已经执行到此处对pSession的资源进行释放从而
//造成内存错误。
if ( pSession->dwCloseTick && dwCurTick - pSession->dwCloseTick >= 10 * 1000 )
{
if(pSession->nSocket != INVALID_SOCKET)
{
OutputMsg( rmWaning, "Socket%d 标记为删除",(int)pSession->nSocket );
}
LOCK_SESSION_SEND( pSession );
pSession->nSocket = INVALID_SOCKET;
pSession->nVerifyIdx = 0;
if ( pSession->RecvBuf.lpBuffer )
{
free( pSession->RecvBuf.lpBuffer );
pSession->RecvBuf.lpBuffer = NULL;
}
pSession->RecvBuf.nSize = pSession->RecvBuf.nOffset = 0;
if ( pSession->SendBuf.lpBuffer )
{
free( pSession->SendBuf.lpBuffer );
pSession->SendBuf.lpBuffer = NULL;
}
pSession->SendBuf.nSize = 0;//SendBuf.nOffset值由发送线程维护
pSession->boMarkToClose = false;
pSession->boRemoteClosed = false;
pSession->dwCloseTick = 0;
UNLOCK_SESSION_SEND( pSession );
}
}
else if ( pSession->nSocket != INVALID_SOCKET )
{
if (dwCurTick - pSession->dwClientMsgTick >= dwCloseIdleSessionLong)
{
OutputMsg( rmWaning, "客户端IdledwCurTick=%ld,dwClientMsgTick=%ld",(long long)dwCurTick, (long)pSession->dwClientMsgTick);
SendCloseSession( pSession, TRUE, enReasonIdle );
}
if(dwCurTick - pSession->dwServerMsgTick >= dwCloseIdleSessionLong)
{
//OutputMsg( rmWaning, "服务器较长时间处于非活动状态的会话,关闭会话" );
//OutputMsg( rmWaning, "服务器端idledwCurTick=%I64d,dwClientMsgTick=%I64d",(long long)dwCurTick, (long long)pSession->dwServerMsgTick);
//SendCloseSession( pSession, TRUE, enReasonIdle );
}
}
}
LeaveCriticalSection( &m_SessionLock );
}
return boResult;
}
char* getDescBySysId(int id)
{
switch (id)
{
case 0:
return "默认系统";
break;
case 1:
return "移动系统";
break;
case 2:
return "属性系统";
break;
case 3:
return "观察系统";
break;
case 4:
return "Buff系统";
break;
case 5:
return "技能系统";
break;
case 6:
return "任务系统";
break;
case 7:
return "装备系统";
break;
case 8:
return "背包系统";
break;
case 9:
return "聊天系统";
break;
case 10:
return "帮会系统";
break;
case 11:
return "技能标记";
break;
case 12:
return "商城系统";
break;
case 13:
return "交易系统";
break;
case 14:
return "玩家变量";
break;
case 15:
return "拾取系统";
break;
case 16:
return "队伍系统";
break;
case 17:
return "操练系统";
break;
case 18:
return "兵魂系统";
break;
case 20:
return "副本系统";
break;
case 21:
return "交互系统";
break;
case 22:
return "消息系统";
break;
case 23:
return "仓库系统";
break;
case 24:
return "PK系统";
break;
case 26:
return "杂七杂八";
break;
case 27:
return "交易行";
break;
case 28:
return "成就系统";
break;
case 30:
return "特效系统";
break;
case 34:
return "宠物系统";
break;
case 35:
return "交通工具";
break;
case 36:
return "盗梦空间";
break;
case 39:
return "摆摊系统";
break;
case 41:
return "好友系统";
break;
case 43:
return "宝石系统";
break;
case 44:
return "英雄系统";
break;
case 45:
return "载具系统";
break;
case 49:
return "BOSS系统";
break;
case 50:
return "邮件系统";
break;
case 51:
return "衣橱系统";
break;
case 52:
return "加速外挂";
break;
case 54:
return "新头衔";
break;
case 57:
return "职业竞技";
break;
case 128:
return "脚本";
break;
case 129:
return "NPC交易";
break;
case 130:
return "装备修理";
break;
case 134:
return "技能快捷键";
break;
case 137:
return "内劲系统";
break;
case 138:
return "福利系统";
break;
case 139:
return "脚本乱七八糟";
break;
case 140:
return "功勋系统";
break;
case 145:
return "活动系统";
break;
case 255:
return "登陆系统";
break;
default:
return "错误!";
break;
}
}
VOID CRunDataProcesser::CheckSendSessionBuffers(PRUNDATASENDTHREAD pSendThread)
{
DECLARE_FUN_TIME_PROF();
static char sSendCheckBuf[RUNGATE_ONCESENDUSE_LIMIT];
int nErr, nRemainSize;
char *pBuffer;
PRUNGATEUSERSESSION pSession = &m_Sessions[pSendThread->nThreadIdx];
pSendThread->boSendEWouldBlock = false;
pSendThread->boSendFewBuffer = false;
for ( ;pSession <= &m_Sessions[m_nMaxSessionCount-1]; pSession += m_nSendThreadCount )
{
if ( pSession->nSocket != INVALID_SOCKET && !pSession->boMarkToClose && !pSession->boRemoteClosed )
{
if ( !pSession->boSendAvaliable )
{
if ( _getTickCount() >= pSession->dwSendTimeOut )
{
pSession->boSendAvaliable = true;
pSession->dwSendTimeOut = 0;
}
else continue;
}
if ( TRYLOCK_SESSION_SEND( pSession ) )
{
nRemainSize = pSession->SendBuf.nOffset;
if ( nRemainSize > 4096 * 1024 )
{
SendCloseSession( pSession, TRUE, enReasonSenderBuffLarge );
nRemainSize = 0;
OutputMsg( rmWaning, "关闭了一个发送数据队列大于4MB的连接。" );
}
if ( nRemainSize )
{
pBuffer = pSession->SendBuf.lpBuffer;
if ( nRemainSize >= MAXINT )//不让它执行这段代码
{
sSendCheckBuf[0] = '*';
memcpy( &sSendCheckBuf[1], pBuffer, RUNGATE_ONCESENDUSE_LIMIT -1 );
nErr = ::send( pSession->nSocket, sSendCheckBuf, RUNGATE_ONCESENDUSE_LIMIT, 0 );
if ( nErr > 0 )
{
if ( nErr != RUNGATE_ONCESENDUSE_LIMIT )
pSendThread->boSendFewBuffer = true;
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -(nErr - 1) );
InterlockedExchangeAdd( (LONG*)&m_dwSendUserSize, nErr );
nRemainSize -= nErr - 1;
memcpy( pBuffer, &pBuffer[nErr - 1], nRemainSize );
pSession->SendBuf.nOffset = nRemainSize;
pBuffer[nRemainSize] = 0;
pSession->nSendPacketCount++;
}
else if ( !nErr || WSAGetLastError() != WSAEWOULDBLOCK )
{
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -pSession->SendBuf.nOffset );
pSession->boRemoteClosed = true;
pSession->SendBuf.nOffset = 0;
SendCloseSession( pSession, TRUE, enReasonSocketError );
}
else
{
pSession->boSendAvaliable = false;
pSession->dwSendTimeOut = _getTickCount() + RUNGATE_SENDCHECK_TIMEOUT;
pSendThread->boSendEWouldBlock = true;
}
}
else
{
TICKCOUNT nCurTick = _getTickCount();
if (nCurTick < pSession->nLastSendPacketTime)
pSession->nLastSendPacketTime = 0;
if (nCurTick - pSession->nLastSendPacketTime >= 15)
{
pSession->nLastSendPacketTime = nCurTick;
nErr = ::send( pSession->nSocket, pBuffer, nRemainSize, 0 );
if ( nErr > 0 )
{
pSession->nSendPacketCount++;
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -nErr );
InterlockedExchangeAdd( (LONG*)&m_dwSendUserSize, nErr );
if ( nErr < nRemainSize )
{
pSendThread->boSendFewBuffer = true;
memcpy( pBuffer, &pBuffer[nErr], nRemainSize - nErr );
nRemainSize -= nErr;
pBuffer[nRemainSize] = 0;
pSession->SendBuf.nOffset = nRemainSize;
pSession->nTimeStampOffset = nRemainSize;
}
else
{
pBuffer[0] = 0;
pSession->SendBuf.nOffset = 0;
pSession->nTimeStampOffset = 0;
}
#ifdef _DEBUG_GATEMSG
char * pIp = inet_ntoa(pSession->SockAddr.sin_addr);
OutputMsg( rmTip, "[%s]Idx=%d: 发到客户端, 已发长度%d, 剩余待发%d;",
pIp, pSession->nVerifyIdx, nErr, pSession->SendBuf.nOffset);
#endif
}
else
{
int nErrorId = WSAGetLastError();
if ( !nErr || nErrorId != WSAEWOULDBLOCK )
{
OutputMsg(rmWaning,"Socket =%d,send fail, errorid=%d ",(int)pSession->nSocket,nErrorId);
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -nRemainSize );
InterlockedExchangeAdd( (LONG*)&m_dwSendUserSize, nRemainSize );
pBuffer[0] = 0;
pSession->SendBuf.nOffset = 0;
}
else
{
pSession->boSendAvaliable = false;
pSession->dwSendTimeOut = _getTickCount() + RUNGATE_SENDCHECK_TIMEOUT;
pSendThread->boSendEWouldBlock = true;
}
}
}
}
}
UNLOCK_SESSION_SEND( pSession );
}
}
else
{
//会话关闭后减少待发送数据统计值
if ( nRemainSize = pSession->SendBuf.nOffset )
{
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendUserSize, -nRemainSize );
pSession->SendBuf.nOffset = 0;
}
}
}
}
//发送数据到服务器
VOID CRunDataProcesser::SendServerMessage(int nIdent, int nSessionIdx, SOCKET nSocket, int nServerIdx, char *pBuffer, int nBufSize)
{
if ( !connected() )
return;
PutMessage(nIdent, nSessionIdx, nSocket, nServerIdx, m_llSvrTimeDiff, pBuffer, nBufSize);
/*
if (GM_CHECKCLIENT != nIdent && GM_CHECKSERVER != nIdent && GM_DATA != nIdent)
{
TRACE( _T("向后台发送命令CMD=%d,socketID=%d,nSessionIdx=%d,nServerIdx=%d\n"), nIdent,nSocket,nSessionIdx,nServerIdx);
}
if (nIdent == GM_DATA)
{
OutputMsg( rmTip, _T("向后台发送数据size=%d,nSocket=%d,nSessionIdx=%d,nServerIdx=%d"),nBufSize,nSocket,nSessionIdx,nServerIdx);
}
*/
/* --begin 老的发送给服务器数据代码
//这个是消息头
RUNGATEMSGHDR Hdr;
Hdr.dwGateCode = RUNGATECODE;
Hdr.nSocket = nSocket;
Hdr.wSessionIdx = nSessionIdx;
Hdr.wIdent = nIdent;
Hdr.wServerIdx = nServerIdx;
Hdr.nDataSize = nBufSize;
Hdr.tickCount = m_llSvrTimeDiff + _getTickCount();
SIZE_T headSize = sizeof(Hdr);
CDataPacket &packet = allocSendPacket();
packet << Hdr;
packet.writeBuf(pBuffer, nBufSize);
flushSendPacket(packet);
---end of 老的发送数据给服务器代码
*/
/*
char buff [MAX_SEND_BUFF_SIZE];
size_t headSize = sizeof(Hdr);
size_t totalSize = headSize + nBufSize;
if (totalSize > MAX_SEND_BUFF_SIZE)
{
GotError( __FUNCTION__, _T("发送包的长度过大"), nBufSize );
return;
}
memcpy(buff,&Hdr,headSize);
memcpy((buff+headSize),pBuffer,nBufSize);
*/
//AppendSendBuffer(&Hdr,headSize );
//AppendSendBuffer(pBuffer,nBufSize );
/* 这里使用的是pipe,修改为socket发送
RUNGATEMSGHDR Hdr;
DWORD dwBytesWriten;
if ( m_hPipe != INVALID_HANDLE_VALUE )
{
Hdr.dwGateCode = RUNGATECODE;
Hdr.nSocket = nSocket;
Hdr.wSessionIdx = nSessionIdx;
Hdr.wIdent = nIdent;
Hdr.wServerIdx = nServerIdx;
Hdr.nDataSize = nBufSize;
#pragma __CPMSG__("----------------修改此处WriteFile为Socket的AppendSendData")
if ( !WriteFile( m_hPipe, &Hdr, sizeof(Hdr), &dwBytesWriten, NULL ) )
{
GotError( __FUNCTION__, "WriteFile", GetLastError() );
ServerPipeError();
}
else if ( nBufSize > 0 && !WriteFile( m_hPipe, pBuffer, nBufSize, &dwBytesWriten, NULL ) )
{
GotError( __FUNCTION__, "WriteFile", GetLastError() );
ServerPipeError();
}
}
*/
}
/*
* 解包WebSocket数据
* param[in] pSession 用户会话
* param[] pInBuff 输入的数据包
* param[] nInSize 输入的数据包的长度
* param[] pOutBuff 输出的数据包指针
* param[] nOutSize 输出的数据包的长度
* param[] nInProcessSize 输入的数据包处理了的长度如果大于0那么前面的这个字节的数据包可以丢弃了
* param[] nOutProcessSize 处理好的数据长度处理好的数据放在pOutBuff里
* ret 如果进行了数据处理返回true否则返回false。数据处理包括发现前面有无效数字拷贝了一个完整的数据包丢弃一些字节等
*/
static bool WebSocketDataUnpack(PRUNGATEUSERSESSION pSession,
char* pInBuff, SIZE_T nInSize,
char* pOutBuff, SIZE_T nOutSize,
SIZE_T& nInProcessSize, SIZE_T& nOutProcessSize)
{
pSession->webSocketHead.reset();
nInProcessSize = 0;
nOutProcessSize = 0;
if (NULL == pInBuff || NULL == pOutBuff) return false;
char* pdata = pInBuff;
SIZE_T nLeftSize = nInSize;
#define WEBSOCKET_READ(_TYPE) *((_TYPE*)pdata); nLeftSize -= sizeof(_TYPE); pdata += sizeof(_TYPE)
//读取websocket固定包头
if (!pSession->webSocketHead.rh)
{
//长度不满足
if (nLeftSize < 2) return false;
//读取
uint8_t head = WEBSOCKET_READ(uint8_t);
pSession->webSocketHead.fin = head >> 7;
pSession->webSocketHead.opcode = emOpcode(head & 0xF);
head = WEBSOCKET_READ(uint8_t);
pSession->webSocketHead.len = head & 0x7F;
pSession->webSocketHead.mask = head >> 7;
pSession->webSocketHead.rh = 1;//标记头部读取完成
nInProcessSize += 2;//记录处理长度
}
//读取长度
if (!pSession->webSocketHead.rl)
{
uint8_t nsize = pSession->webSocketHead.GetLenNeedByte();
if (nsize)
{
//这个包不够一个长度
if (nLeftSize < nsize) return false;
if (nsize == 2) {
pSession->webSocketHead.ex_len.v16 = WEBSOCKET_READ(uint16_t);
pSession->webSocketHead.ex_len.v16 = ntohs(pSession->webSocketHead.ex_len.v16);
nInProcessSize += 2; //记录处理长度
} else {
pSession->webSocketHead.ex_len.v64 = WEBSOCKET_READ(uint64_t);
pSession->webSocketHead.ex_len.v64 = ntohl((u_long)pSession->webSocketHead.ex_len.v64);
nInProcessSize += 8; //记录处理长度
}
}
pSession->webSocketHead.rl = 1;
}
//读取MKEY
if (!pSession->webSocketHead.rk)
{
if (pSession->webSocketHead.mask) {
//这个包不够一个key长度
if (nLeftSize < 4) return false;
pSession->webSocketHead.mkey[0] = WEBSOCKET_READ(uint8_t);
pSession->webSocketHead.mkey[1] = WEBSOCKET_READ(uint8_t);
pSession->webSocketHead.mkey[2] = WEBSOCKET_READ(uint8_t);
pSession->webSocketHead.mkey[3] = WEBSOCKET_READ(uint8_t);
nInProcessSize += 4; //记录处理长度
}
pSession->webSocketHead.rk = 1;
}
//读取数据段
uint64_t data_len = pSession->webSocketHead.GetLen();
if (nLeftSize < data_len) return false;
// 掩码处理
if (pSession->webSocketHead.mask)
{
char* dptr = pdata;
for (size_t i = 0; i < data_len; ++i) {
dptr[i] = dptr[i] ^ pSession->webSocketHead.mkey[i % 4];
}
}
memcpy(pOutBuff,(void *)(pInBuff + nInProcessSize), data_len);
//OutputMsg( rmTip, "Websocket数据(头长:%ld, 数据长:%ld)", nInProcessSize, data_len, *((int*)pInBuff));
nInProcessSize += data_len;
nOutProcessSize = data_len;
return true;
}
//收到用户的数据包
VOID CRunDataProcesser::ProcessUserRecvPacket(PRUNGATEUSERSESSION pSession, char *pBuffer, int nBufferSize)
{
DECLARE_FUN_TIME_PROF();
//static const char szFlashSocketPolicyRequest[] = "<policy-file-request/>";
//static const char szFlashSocketPolicyRequestReply[]= "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>";
//static int s_policyStrLen = (int)strlen(szFlashSocketPolicyRequest) +1; //请求安全策略文件的长度,后面都是以\0结尾的
//static int s_policyReplyStrLen = (int)strlen(szFlashSocketPolicyRequestReply) +1;//回复安全策略文件的长度
InterlockedExchangeAdd( (LONG*)&m_dwProcessRecvSize, nBufferSize );
//session中已缓存的数据剩下待处理的数据
int nLeftDataSize = pSession->RecvBuf.nOffset + nBufferSize + 1;
if ( pSession->RecvBuf.nSize < nLeftDataSize )
{
pSession->RecvBuf.nSize = (nLeftDataSize / SESSION_DATAGROW_SIZE + 1) * SESSION_DATAGROW_SIZE;
pSession->RecvBuf.lpBuffer = (char*)realloc( pSession->RecvBuf.lpBuffer, pSession->RecvBuf.nSize );
}
nLeftDataSize--;
//将数据拷贝过来
char *pDataBuffer;
pDataBuffer = pSession->RecvBuf.lpBuffer;
memcpy( &pDataBuffer[pSession->RecvBuf.nOffset], pBuffer, nBufferSize );
pSession->RecvBuf.nOffset = nLeftDataSize;
pDataBuffer[nLeftDataSize] = 0;
//如果剩余数据超过峰值则丢弃
if ( pSession->RecvBuf.nOffset >= SESSION_MAX_RECVPROC_SIZE )
{
pSession->RecvBuf.nOffset = 0;
SendCloseSession( pSession, TRUE, enReasonLargePackLeft );
return;
}
//输出日志
#ifdef _DEBUG_GATEMSG
//char * pIp = inet_ntoa(pSession->SockAddr.sin_addr);
OutputMsg( rmTip, "Idx=%ld: 准备处理socket数据, session状态为%d, 当前接收缓存为%d;",
pSession->nVerifyIdx, pSession->nSessionSatus, nLeftDataSize);
#endif
//SIZE_T nPolicyStrSize = (int)strlen(szFlashSocketPolicyRequest);
//处理Session的buffer
char pDataProcBuf[MAX_SEND_BUFF_SIZE];
#ifdef _DEBUG_GATEMSG
memset(pDataProcBuf, 0, MAX_SEND_BUFF_SIZE);
#endif
while ( nLeftDataSize > 0 )
{
if ( pSession->wPacketError >= SESSION_PACKETERR_MAX )
{
nLeftDataSize = 0;
SendCloseSession( pSession, TRUE, enReasonRecvLargerPack );
OutputMsg( rmWaning, "wPacketError=%d,超出了",pSession->wPacketError);
break;
}
if ( pSession->boMarkToClose || pSession->boRemoteClosed )
{
OutputMsg( rmTip, "远程关闭,不处理数据");
break;
}
SIZE_T nBuffSize = pSession->RecvBuf.nOffset ;
//正常通信状态,这个最多放前面
if (pSession->nSessionSatus != enSessionStatusIdle)
{
SIZE_T nInprocessSize =0 ,nOutProcessSize =0;
// Websocket数据解包处理
if (WebSocketDataUnpack(pSession, pDataBuffer, nLeftDataSize,
pDataProcBuf, MAX_SEND_BUFF_SIZE, nInprocessSize, nOutProcessSize))
{
// 调整已处理过的字节
if (nInprocessSize > 0)
{
nLeftDataSize -= (INT)nInprocessSize;
if (nLeftDataSize < 0)
{
nLeftDataSize = 0;
}
else
{
pDataBuffer = (char *)(pDataBuffer + nInprocessSize);
}
}
#ifdef _DEBUG_GATEMSG
OutputMsg( rmTip, "Idx=%ld: 已处理%d, 协议有效长%d, 当前接收缓存为%d;",
pSession->nVerifyIdx, nInprocessSize, nOutProcessSize, nLeftDataSize);
#endif
// 将输出的数据要传递到LogicServer
if (nOutProcessSize > 0)
{
//正常通讯
if (pSession->nSessionSatus == enCommunication)
{
//检查退出
if (pSession->webSocketHead.opcode == emOpcode(0x8))
{
OutputMsg( rmTip, "远程关闭,不处理数据");
SendCloseSession(pSession, TRUE, 1);
return;
}
//检查服务端key
if (nOutProcessSize >= 2)
{
unsigned short tag = *((unsigned short*)pDataProcBuf);
if(tag != pSession->nKey)
{
SendCloseSession(pSession, TRUE, 2);
return;
}
//截去key
char* pOutData = (char*)pDataProcBuf + sizeof(unsigned short);
nOutProcessSize -= sizeof(unsigned short);
//截去验证
uint32_t check = *((uint32_t*)pOutData);
pOutData = pOutData + sizeof(uint32_t);
nOutProcessSize -= sizeof(uint32_t);
//测试代码,数据转发给客户端
//PostUserServerData(pSession, pOutData, (INT)nOutProcessSize, TRUE, TRUE);
#ifdef _DEBUG_GATEMSG
OutputMsg( rmTip, "Idx=%ld: 准备发服务器 [%s] SysID:%d, CmdID:%d;",
pSession->nVerifyIdx, getDescBySysId(*((unsigned char*)pOutData)), *((unsigned char*)pOutData), *((unsigned char*)pOutData + 1));
#endif
//把数据发到服务器
SendServerMessage(GM_DATA, pSession->nIndex, pSession->nSocket,
pSession->nServerIdx, pOutData, (INT)nOutProcessSize);
//OutputMsg( rmTip, "systemID = %d", *((char*)(pOutData)));
//OutputMsg( rmTip, "cmdID = %d", *((char*)(pOutData + 1)));
}
}
//刚连上来
else if(pSession->nSessionSatus == enConn)
{
pSession->nKey = (unsigned short)wrand(INT_MAX);
PostUserServerData(pSession, (char *)&pSession->nKey, 2);
pSession->nSessionSatus = enCommunication;
OutputMsg( rmTip, "=================================================Finish");
}
}
}
else
{
OutputMsg( rmTip, "消息长度不够,等待下一次组包");
break;
}
}
}
//修正Session的buffer
if (pSession->RecvBuf.lpBuffer != NULL)
{
if ( nLeftDataSize > 0 )
{
if ( pDataBuffer != pSession->RecvBuf.lpBuffer )
{
memcpy( pSession->RecvBuf.lpBuffer, &pSession->RecvBuf.lpBuffer[pSession->RecvBuf.nOffset - nLeftDataSize], nLeftDataSize );
pSession->RecvBuf.lpBuffer[nLeftDataSize] = 0;
pSession->RecvBuf.nOffset = nLeftDataSize;
}
}
else
{
pSession->RecvBuf.lpBuffer[0] = 0;
pSession->RecvBuf.nOffset = 0;
}
}
}
int CRunDataProcesser::s_nIgnoreDataPacket = 0;
VOID CRunDataProcesser::PostUserServerData(PRUNGATEUSERSESSION pSession, const char *pBuffer, int nBufferSize, BOOL boWriteWsHdr, BOOL boWriteProtoHdr, TICKCOUNT nSendTime)
{
/*if (s_nIgnoreDataPacket)
{
return;
} */
//OutputMsg( rmTip, "向玩家发送%d个字节数据",nBufferSize);
DECLARE_FUN_TIME_PROF();
char *pDataPtr;
PRUNDATASENDTHREAD pSendThread;
PSENDCLIENTBUF pSendBuf;
PDATAHEADER pProtoHdr;
static char sPrintS2CBuffer[81920];
pSendThread = &m_SendThreads[pSession->nIndex % m_nSendThreadCount];
pSendBuf = (PSENDCLIENTBUF)malloc( nBufferSize + sizeof(*pSendBuf) + 4 + sizeof(*pProtoHdr) + 16);
pSendBuf->pSession = pSession;
int wsheaderLength = 0;
pDataPtr = (char*)(pSendBuf + 1);
CDataPacket pack(pDataPtr, nBufferSize + 4 + sizeof(*pProtoHdr) + 16);
pack.setPosition(0);
// 写入websocket头部
if( boWriteWsHdr )
{
int totallen = boWriteProtoHdr ? nBufferSize + sizeof(uint16_t) : nBufferSize;
pack << (uint8_t)0x82;//写头部
//写长度
if (totallen >= 126) {//7位放不下
if (totallen <= 0xFFFF) {//16位放
pack << (uint8_t)126;
pack << (uint16_t)htons((u_short)totallen);
} else {//64位放
pack << (uint8_t)127;
pack << (uint64_t)OrderSwap64(totallen);
}
} else {
pack << (uint8_t)totallen;
}
}
// 写入协议头部
if ( boWriteProtoHdr )
{
//DATAHEADER ProtoHd;
//ProtoHd.tag = DEFAULT_TAG_VALUE;
//ProtoHd.len = nBufferSize;
//ProtoHd.u.tp = nSendTime - m_llSvrTimeDiff; // 网关收到来自服务器的数据包,盖上时间戳
//ProtoHd.u.tp = __max(0, _getTickCount() - (nSendTime - m_llSvrTimeDiff));
//pack.writeBuf(&ProtoHd, sizeof(DATAHEADER));
//写数据
pack << (uint16_t)pSession->nKey;
}
//写数据
pack.writeBuf(pBuffer, nBufferSize);
// 写入数据总长度
pack.setPosition(0);
pSendBuf->nBufferSize = pack.getAvaliableLength();
#ifdef _DEBUG_GATEMSG
OutputMsg( rmTip, "Idx=%d: 准备发客户端 [%s] SysID:%d, CmdID:%d, 数据长:%d, 协议有效长:%d",
pSession->nVerifyIdx, getDescBySysId(*((unsigned char*)pBuffer)), *((unsigned char*)pBuffer), *((unsigned char*)pBuffer + 1), pSendBuf->nBufferSize, nBufferSize);
#endif
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendQueueSize, nBufferSize );
EnterCriticalSection( &pSendThread->SendQueueLock );
pSendThread->pSendAppendList->add( pSendBuf );
LeaveCriticalSection( &pSendThread->SendQueueLock );
}
/*
VOID CRunDataProcesser::PostUserServerRawData(PRUNGATEUSERSESSION pSession, const char *pBuffer, DWORD dwBufferSize)
{
char *pDataPtr;
PRUNDATASENDTHREAD pSendThread;
PSENDCLIENTBUF pSendBuf;
pSendThread = &m_SendThreads[pSession->nIndex % m_nSendThreadCount];
if (dwBufferSize > 0)
{
pSendBuf = (PSENDCLIENTBUF)malloc( sizeof(*pSendBuf) + dwBufferSize + 1 );
pSendBuf->pSession = pSession;
pDataPtr = (char*)(pSendBuf + 1);
memcpy( pDataPtr, pBuffer, dwBufferSize );
pDataPtr[dwBufferSize] = 0;
pSendBuf->nBufferSize = dwBufferSize;
InterlockedExchangeAdd( (LONG*)&m_dwWaitSendQueueSize, dwBufferSize );
}
EnterCriticalSection( &pSendThread->SendQueueLock );
pSendThread->pSendAppendList->add( pSendBuf );
LeaveCriticalSection( &pSendThread->SendQueueLock );
}
*/
INT CRunDataProcesser::GetActiveUserCount()
{
return m_nActiveUser;
}
VOID CRunDataProcesser::SetName(LPCSTR sName)
{
ZeroMemory( m_sGateName, sizeof(m_sGateName) );
strncpy( m_sGateName, sName, __min(sizeof(m_sGateName)-1, strlen(sName)) );
SetClientName(sName);
}
/*
VOID CRunDataProcesser::SetPipeName(LPCSTR sPipeName)
{
ZeroMemory( m_sPipeName, sizeof(m_sPipeName) );
strncpy( m_sPipeName, sPipeName, __min(sizeof(m_sPipeName)-1, strlen(sPipeName)) );
}
*/
INT CRunDataProcesser::GetSendThreadCount()
{
return m_nSendThreadCount;
}
VOID CRunDataProcesser::SetSendThreadCount(INT ThreadCount)
{
if ( !m_boStarted && ThreadCount > 0 && ThreadCount <= RUNDATA_MAX_SENDTHREAD )
{
m_nSendThreadCount = ThreadCount;
}
}
DATAPROCESSERTYPE CRunDataProcesser::GetDataProcessType()
{
return m_DataProcessType;
}
VOID CRunDataProcesser::SetDataProcessType(DATAPROCESSERTYPE Type)
{
m_DataProcessType = Type;
}
VOID CRunDataProcesser::SetRunSockProcesser(CRunSockProcesser* pSockProcesser)
{
m_pSockProcesser = pSockProcesser;
}
INT CRunDataProcesser::GetMaxSessionCount()
{
return m_nMaxSessionCount;
}
PRUNDATASENDTHREAD CRunDataProcesser::GetSendThreadInfo(INT ThreadIdx)
{
if ( ThreadIdx >= 0 && ThreadIdx < RUNDATA_MAX_SENDTHREAD )
{
if ( m_SendThreads[ThreadIdx].hThread )
return &m_SendThreads[ThreadIdx];
}
return NULL;
}
PRUNGATEUSERSESSION CRunDataProcesser::GetFirstSession()
{
return m_Sessions;
}
VOID CRunDataProcesser::SetPrintC2SMessage(const BOOL boPrint)
{
m_boPrintC2SMsg = boPrint;
}
VOID CRunDataProcesser::SetPrintS2CMessage(const BOOL boPrint)
{
m_boPrintS2CMsg = boPrint;
}
BOOL CRunDataProcesser::Startup()
{
int i;
m_boStoping = FALSE;
m_dwWaitSendUserSize = 0;
m_dwWaitSendQueueSize = 0;
m_dwLastProcUsrMsgTime = 0;
m_dwLastProcSrvMsgTime = 0;
m_dwLastRecvSrvMsgTime = 0;
m_dwRecvSeverSize = 0;
m_dwSendUserSize = 0;
m_dwProcSrvThreadSleep = 0;
m_dwSendQueueSize = 0;
//初始化会话队列
InitSessions();
//创建用户数据处理线程
#ifdef _MSC_VER
m_hProcRecvThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)RecvDataProcessRoutine, this, 0, NULL );
if ( !m_hProcRecvThread )
{
GotError( __FUNCTION__, _T("CreateThread"), GetLastError() );
return FALSE;
}
#else
if (pthread_create(&m_hProcRecvThread, NULL, RecvDataProcessRoutine, this)) {
return FALSE;
}
#endif
//创建用户数据发送线程
for ( i=0; i<m_nSendThreadCount; ++i )
{
m_SendThreads[i].pRunData = this;
m_SendThreads[i].nThreadIdx = i;
m_SendThreads[i].boSendEWouldBlock = false;
m_SendThreads[i].boSendFewBuffer = false;
#ifdef _MSC_VER
m_SendThreads[i].hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)SendDataProcessRoutine, &m_SendThreads[i], 0, &m_SendThreads[i].dwThreadId );
if ( !m_SendThreads[i].hThread )
{
GotError( __FUNCTION__, _T("CreateThread"), GetLastError() );
return FALSE;
}
#else
if (pthread_create(&(m_SendThreads[i].hThread), NULL, SendDataProcessRoutine, &m_SendThreads[i])) {
return FALSE;
}
#endif
}
if ( Inherited::Startup() )
{
m_boStarted = TRUE;
return TRUE;
}
else return FALSE;
}
int CRunDataProcesser::ChangeConsoleLine(int nLine, int nPos, LPCSTR sFormat, ...)
{
COORD cPos;
va_list args;
cPos.X = nPos;
cPos.Y = nLine;
#ifdef _MSC_VER
SetConsoleCursorPosition( g_hStdOut, cPos );
#endif
va_start(args, sFormat);
cPos.X = vfprintf( stdout, sFormat, args );
va_end(args);
return cPos.X;
}
VOID CRunDataProcesser::ShowGateStatus(CRunDataProcesser *pRunData)
{
int i, nLine = 0;
PRUNDATASENDTHREAD pSendThread;
ChangeConsoleLine( nLine, 0, "---------------------网关状态[%s]-----------------\n", pRunData->GetName());
nLine++;
ChangeConsoleLine( nLine, 0, "活动连接数:%d \n", pRunData->GetActiveUserCount() );
nLine++;
ChangeConsoleLine( nLine, 0, "接收用户数据: %dB 发送用户数据: %dKB 待发用户数据: %dKB 待发用户队列: %dKB \n",
pRunData->m_dwProcessRecvSize, pRunData->m_dwSendUserSize / 1024, pRunData->m_dwWaitSendUserSize / 1024,
pRunData->m_dwSendQueueSize / 1024 );
nLine++;
ChangeConsoleLine( nLine, 0, "接收引擎数据: %dKB 接收数据时间: %d毫秒 引擎数据处理: %d毫秒 用户数据处理: %d毫秒 \n",
pRunData->m_dwRecvSeverSize / 1024, pRunData->m_dwLastRecvSrvMsgTime, pRunData->m_dwLastProcSrvMsgTime,
pRunData->m_dwLastProcUsrMsgTime );
nLine++;
for ( i=0; i<RUNDATA_MAX_SENDTHREAD; ++i )
{
pSendThread = pRunData->GetSendThreadInfo( i );
if ( !pSendThread )
continue;
ChangeConsoleLine( nLine, 0, "发送线程%d[数据处理: %d毫秒 休眠时间: %d毫秒 标志:%d/%d] \n",
i, pSendThread->dwProcTick, pSendThread->dwSleepTick, pSendThread->boSendEWouldBlock, pSendThread->boSendFewBuffer );
nLine++;
InterlockedExchange( (LONG*)&pSendThread->dwProcTick, 0 );
InterlockedExchange( (LONG*)&pSendThread->dwSleepTick, 0 );
}
ChangeConsoleLine( nLine, 0, "服务器数据处理线程休眠: %d毫秒\n",
pRunData->m_dwProcSrvThreadSleep );
nLine++;
ChangeConsoleLine( nLine, 0, "----------------------------------------------------------------\n" );
nLine++;
pRunData->Dump();
InterlockedExchange( (LONG*)&pRunData->m_dwProcessRecvSize, 0 );
InterlockedExchange( (LONG*)&pRunData->m_dwSendUserSize, 0 );
InterlockedExchange( (LONG*)&pRunData->m_dwRecvSeverSize, 0 );
}
VOID CRunDataProcesser::Stop()
{
int i;
m_boStoping = TRUE;
Inherited::Stop();
CloseThread( m_hProcRecvThread );
for ( i=0; i<m_nSendThreadCount; ++i )
{
if ( m_SendThreads[i].hThread )
{
CloseThread( m_SendThreads[i].hThread );
FreeSendBuffers( &m_SendThreads[i] );
}
}
//CloseServerPipe();
if ( m_ServerBuf.lpBuffer )
{
free( m_ServerBuf.lpBuffer );
m_ServerBuf.lpBuffer = NULL;
}
m_ServerBuf.nOffset = m_ServerBuf.nSize = 0;
FreeRecvBuffers();
//FreeSendBuffers();
CancelRemainSendSessionBuffers();
CloseAllSessions( TRUE );
UninitSessions();
m_boStarted = FALSE;
}
//创建一个Session
PRUNGATEUSERSESSION CRunDataProcesser::NewSession(SOCKET nSocket, SOCKADDRIN RemoteAddr)
{
if (!connected())
{
return NULL;
}
int i;
PRUNGATEUSERSESSION pSession, pNewSession = NULL;
/*
if ( m_hPipe == INVALID_HANDLE_VALUE )
return NULL;
*/
OutputMsg( rmTip, "=================================================Begin");
OutputMsg( rmTip, "开始接入新的socket=%d", (int)nSocket);
EnterCriticalSection( &m_SessionLock );
pSession = m_Sessions;
for ( i=0; i<m_nMaxSessionCount; ++i )
{
//这里安潮发现一个问题在多线程的情况下一个线程要了一个session,然后睡眠了另外一个线程可能依然获得这个session
if ( pSession->nSocket == INVALID_SOCKET &&
!pSession->boMarkToClose &&
!pSession->boRemoteClosed &&
!pSession->dwCloseTick &&
pSession->nSessionSatus ==enSessionStatusIdle)
{
pNewSession = pSession;
pNewSession->SendBuf.nOffset = 0;
pNewSession->dwCloseTick = 0;
pNewSession->boMarkToClose = false;
pNewSession->boRemoteClosed = false;
pNewSession->nSessionSatus = enConn;
break;
}
pSession++;
}
LeaveCriticalSection( &m_SessionLock );
if ( pNewSession )
{
pNewSession->SockAddr = RemoteAddr;
pNewSession->nServerIdx = 0;
pNewSession->btPacketIdx = 0;
pNewSession->wPacketError = 0;
pNewSession->nRecvPacketCount=0;
pNewSession->nSendPacketCount=0;
pNewSession->boMarkToClose = false;
pNewSession->boRemoteClosed = false;
pNewSession->boSendAvaliable= true;
pNewSession->dwSendTimeOut = 0;
pNewSession->dwCloseTick = 0;
pNewSession->dwConnectTick = _getTickCount();
pNewSession->dwClientMsgTick= pNewSession->dwConnectTick;
pNewSession->dwServerMsgTick= pNewSession->dwConnectTick;
pNewSession->nVerifyIdx = InterlockedIncrement( (unsigned long long*)&m_nUserVerify );
pNewSession->webSocketHead.reset();
pNewSession->webSocketShakeHand = false;
pNewSession->sLoginAccount[0] = 0;
pNewSession->sLoginCharName[0]= 0;
//pNewSession->nSessionId = 0;
if ( !pNewSession->RecvBuf.lpBuffer )
{
pNewSession->RecvBuf.nSize = SESSION_RECV_BUFSIZE ;
pNewSession->RecvBuf.lpBuffer = (char*)malloc( pNewSession->RecvBuf.nSize );
}
pNewSession->RecvBuf.nOffset = 0;
#ifdef WIN32
pNewSession->Overlapped.WSABuf.buf = pNewSession->sRecvBuf;
pNewSession->Overlapped.WSABuf.len = sizeof(pNewSession->sRecvBuf) - 1;
#endif
pNewSession->sRecvBuf[sizeof(pNewSession->sRecvBuf)] = 0;
if ( !pNewSession->SendBuf.lpBuffer )
{
pNewSession->SendBuf.nSize = SESSION_SEND_BUFSIZE ;
pNewSession->SendBuf.lpBuffer = (char*)malloc( pNewSession->SendBuf.nSize );
}
pNewSession->SendBuf.nOffset = 0;
//最后设置会话的nSocket成员数据
//以防止其他线程通过nSocket != INVALID_SOCKET判断后对一个尚为初始化完毕的会话进行操作
pNewSession->nSocket = nSocket;
pNewSession->nSessionSatus = enConn; //开始处于连接状态
char * pIp = inet_ntoa(RemoteAddr.sin_addr);
OutputMsg( rmTip, "[%s]接入新的socket=%d 完毕,nVerifyIdx=%ld",pIp, (int)nSocket,pNewSession->nVerifyIdx);
m_nActiveUser++; //增加活动用户计数
struct timeval tv_timeout;
tv_timeout.tv_sec = 10;
tv_timeout.tv_usec = 0;
setsockopt(nSocket,SOL_SOCKET,SO_RCVTIMEO,&tv_timeout, sizeof(tv_timeout));
setsockopt(nSocket,SOL_SOCKET,SO_SNDLOWAT,&tv_timeout, sizeof(tv_timeout));
int nErr = ::recv(pNewSession->nSocket, pNewSession->sRecvBuf, sizeof(pNewSession->sRecvBuf)-1, 0);
if ( nErr > 0 )
{
pNewSession->sRecvBuf[nErr] = 0;
AddRecvBuf( pNewSession, pNewSession->nVerifyIdx, pNewSession->sRecvBuf, nErr );
}
else if (nErr == SOCKET_ERROR)
{
pNewSession->boRemoteClosed = true;
SendCloseSession( pNewSession, TRUE, 2002 );
}
}
return pNewSession;
}
static bool gFindHttpParam(const char * param, const char * buf) {
while (*param == *buf) {
if (*(param + 1) == '\0') return true;
++param; ++buf;
}
return false;
}
#define WEB_SOCKET_HANDS_RE "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: %s\r\n\r\n"
#define MAGIC_KEY "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
VOID CRunDataProcesser::ShakeHandsHandle(PRUNGATEUSERSESSION pSession, char* pBuffer, int BufferSize) {
char key[512]; memset(key, 0, 512);
for (int i = 0; i < BufferSize; ++i)
{
if (gFindHttpParam("Sec-WebSocket-Key", pBuffer+i)) {
short k = i + 17, ki = 0;
while(*(pBuffer + k) != '\r' && *(pBuffer + k) != '\n') {
if (*(pBuffer + k) == ':' || *(pBuffer + k) == ' '){
++k; continue;
} else {
key[ki++] = *(pBuffer + k);
}
++k;
}
break;
}
}
//MSG_LOG("key:%s...", key);
memcpy(key + strlen(key), MAGIC_KEY, sizeof(MAGIC_KEY));
//MSG_LOG("megerkey:%s...", key);
//求哈希1
SHA1 sha;
unsigned int message_digest[5];
sha.Reset();
sha << key;
sha.Result(message_digest);
for (int i = 0; i < 5; i++) {
message_digest[i] = htonl(message_digest[i]);
}
memset(key, 0, 512);
base64_encode(key, reinterpret_cast<const char*>(message_digest), 20);
char http_res[512] = "";
sprintf(http_res, WEB_SOCKET_HANDS_RE, key);
PostUserServerData(pSession, http_res, strlen(http_res), false, false);
//MSG_LOG("res:%s...",http_res);//fkYTdNEVkParesYkrM4S
pSession->webSocketShakeHand = true;
char * pIp = inet_ntoa(pSession->SockAddr.sin_addr);
OutputMsg( rmTip, "[%s]握手完毕,nVerifyIdx=%ld",pIp, pSession->nVerifyIdx);
}
VOID CRunDataProcesser::AddRecvBuf(PRUNGATEUSERSESSION pSession,unsigned long long nVerify, char *pBuffer, int BufferSize)
{
PCLIENTRECVBUF pRecvBuf;
char *pData;
if ( pSession->nSocket == INVALID_SOCKET || pSession->boMarkToClose || pSession->boRemoteClosed || !nVerify || pSession->nVerifyIdx != nVerify )
return;
//--pSession->boSendAvaliable = true;
char * pIp = inet_ntoa(pSession->SockAddr.sin_addr);
// 未进行websocket握手则先握手
if (pSession->webSocketShakeHand)
{
#ifdef _DEBUG_GATEMSG
OutputMsg( rmNormal, "");
OutputMsg( rmTip, "[%s]Idx=%ld: 接收socket数据, 长度为%d, session状态为%d",
pIp, pSession->nVerifyIdx, BufferSize, pSession->nSessionSatus);
#endif
pRecvBuf = (PCLIENTRECVBUF)malloc( sizeof(*pRecvBuf) + BufferSize + 1 );
pRecvBuf->pSession = pSession;
pRecvBuf->nVerify = nVerify;
pRecvBuf->nBufferSize = BufferSize;
pData = (char*)(pRecvBuf + 1);
memcpy( pData, pBuffer, BufferSize );
pData[BufferSize] = 0;
EnterCriticalSection( &m_RecvQueueLock );
m_pRecvAppendList->add( pRecvBuf );
LeaveCriticalSection( &m_RecvQueueLock );
} else {
OutputMsg( rmTip, "[%s]进行握手, 长度为%d, session状态为%d, nVerifyIdx=%ld",
pIp, BufferSize, pSession->nSessionSatus, pSession->nVerifyIdx);
//OutputMsg( rmTip, "握手数据:\n%s", pBuffer);
ShakeHandsHandle(pSession, pBuffer, BufferSize);
SendOpenSession(pSession);//发送到LogicServer新增连接
}
}