This commit is contained in:
aixianling
2025-01-09 17:45:40 +08:00
commit 5c9f1dae4a
3482 changed files with 1146531 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
#include "StdAfx.h"
//暂时作废
CCommonServer::CCommonServer() : Inherited()
{
/*m_SessionList.setLock(&m_SessionListLock);*/
SetServiceName(_T("普通逻辑服务器Server"));
}
CCommonServer::~CCommonServer()
{
}
CCustomServerClientSocket* CCommonServer::CreateClientSocket(SOCKET nSocket, PSOCKADDR_IN pAddrIn)
{
OutputMsg(rmTip, _T("接收普通逻辑服务器连接"));
return new CCommonServerClient(this, nSocket, pAddrIn);
}
VOID CCommonServer::DestroyClientSocket(CCustomServerClientSocket *pClientSocket)
{
//m_CloseClientList.add(pClientSocket);
OutputMsg(rmTip, _T("断开普通逻辑服务器连接"));
Inherited::DestroyClientSocket(pClientSocket);
}
VOID CCommonServer::DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4)
{
/*switch(uMsg)
{
}*/
}
VOID CCommonServer::ProcessClients()
{
Inherited::ProcessClients();
ProcessClosedClients();
}
VOID CCommonServer::SingleRun()
{
TICKCOUNT dwCurTick = _getTickCount();
////提交新开启的会话数据
//if ( m_SessionList.appendCount() > 0 )
//{
// m_SessionList.flush();
// TRACE(_T("当前会话数量:%d"), m_SessionList.count());
//}
//调用父类例行执行
Inherited::SingleRun();
}
VOID CCommonServer::ProcessClosedClients()
{
//INT_PTR i;
//CDBDataClient *pClient;
//TICKCOUNT dwCurTick = _getTickCount();
////必须降序循环,因为连接可能在循环中被移除
//for (i = m_CloseClientList.count() - 1; i > -1; --i)
//{
// pClient = m_CloseClientList[i];
// //连接被关闭后依然要调用Run函数因为可能有重要的网络数据或逻辑数据没有处理完
// pClient->Run();
// //连接关闭5分钟后再释放连接对象
// if ( dwCurTick - pClient->m_dwClosedTick >= 5 * 60 * 1000 )
// {
// m_CloseClientList.remove(i);
// delete pClient;
// }
//}
}
VOID CCommonServer::OnRun()
{
}
void CCommonServer::SendData(int nServerIndex, const void *pData, const size_t nLen)
{
static char szData[81960];
if (nLen + sizeof(DATAHEADER) > sizeof(szData))
{
OutputMsg(rmError, _T("%s send too big packet(len=%d)"), __FUNCTION__, nLen);
return;
}
// INT_PTR i, nSendCount = 0;
CCommonServerClient *pClient;
for (INT_PTR i = m_ClientList.count() - 1; i > -1; --i)
{
pClient = (CCommonServerClient *)m_ClientList[i];
if (pClient && pClient->connected() && pClient->registed() && pClient->getClientType() == GameServer)
{
// 封装一个消息头进去
/*PDATAHEADER pHeader;
ZeroMemory(pHeader, sizeof(0));
pHeader->tag = DEFAULT_TAG_VALUE;
CopyMemory((void *)(pHeader+1), pData, nLen);
pClient->AppendSendBuffer(pHeader, nLen + sizeof(DATAHEADER));*/
return;
}
}
return;
}
//
//BOOL CCommonServer::GetSession(const INT_PTR nSessionId, OUT PGAMESESSION pSession)
//{
// BOOL boResult = FALSE;
// CSafeLock sl(&m_SessionListLock);
//
// PGAMESESSION pSessionPtr = GetSessionPtr(nSessionId, NULL);
// if ( pSessionPtr )
// {
// *pSession = *pSessionPtr;
// boResult = TRUE;
// }
//
// return boResult;
//}
//
//PGAMESESSION CCommonServer::GetSessionPtr(const INT_PTR nSessionId, PINT_PTR lpIndex)
//{
// INT_PTR i;
// PGAMESESSION *pSessionList;
//
// pSessionList = m_SessionList;
// for (i= m_SessionList.count() - 1; i > -1; --i)
// {
// if ( pSessionList[i]->nSessionID == nSessionId )
// {
// if (lpIndex) *lpIndex = i;
// return pSessionList[i];
// }
// }
//
// return NULL;
//}

View File

@@ -0,0 +1,62 @@
#ifndef COMMON_SERVER_H_
#define COMMON_SERVER_H_
/*
功能此类是跨服服务器用于连接普通的逻辑服务器的连接Server类。公共逻辑服务器在启动引擎的时候
创建此对象,并且在指定的地址上监听来自普通逻辑服务器的连接。建立和普通服务器的连接之后,就由
CCommonServerClient类负责和客户端的连接处理。CCommonServer只是负责连接的建立和管理
负责具体连接数据的处理。
公共服务器发送给普通逻辑服务器的数据需要找到对应的链接。可以根据ServerIndex来进行索引。
虽然说用ServerIndex索引每次都需要遍历但是考虑到逻辑服务器之间通信不是很频繁定时存盘数据
并且断开后重新连上不会有太多影响等等,还是采取索引方式来连接。
逻辑引擎调用CCommonServer::SendData(serverIndex, pData, nLen)来发送数据。接收数据在
CCommonServerClient里头处理
!!!!!!!!!!!!!!!!暂时作废
*/
class CCommonServerClient;
class CCommonServer : public CCustomServerSocket
{
public:
typedef CCustomServerSocket Inherited;
CCommonServer();
~CCommonServer();
//覆盖创建连接对象的函数
CCustomServerClientSocket* CreateClientSocket(SOCKET nSocket, PSOCKADDR_IN pAddrIn);
//覆盖销毁一个已经建立的客户端对象
VOID DestroyClientSocket(CCustomServerClientSocket *pClientSocket);
//覆盖处理客户端连接的函数
VOID ProcessClients();
//覆盖内部消息分派函数
VOID DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4);
//覆盖例行执行函数
VOID SingleRun();
//覆盖父类调用例行RUN的函数
VOID OnRun();
/*
* Comments: 往指定的服务器发送消息供外部线程调用。最大数据包长度为81960字节
* Param int nServerIndex: 目标服务器ServerIndex
* Param const char * pData:
* Param const size_t nLen:
* @Return void:
* @Remark: 遍历的方式效率很低,最好做成索引的方式! TODO
*/
void SendData(int nServerIndex, const void *pData, const size_t nLen);
private:
//处理已经关闭的数据客户端对象
VOID ProcessClosedClients();
//// 供外部线程调用,需要加锁
//BOOL GetSession(const INT_PTR nSessionId, OUT PGAMESESSION pSession);
//// 供内部调用,无需加锁
//PGAMESESSION GetSessionPtr(const INT_PTR nSessionId, PINT_PTR lpIndex);
private:
//CBaseList<CCommonServerClient*> m_CloseClientList; //已经关闭的数据客户端列表
/*CQueueList<PGAMESESSION> m_SessionList;
CCSLock m_SessionListLock;*/
};
#endif

View File

@@ -0,0 +1,94 @@
#include "StdAfx.h"
CCommonServerClient::CCommonServerClient(CCommonServer *lpCommonServer, SOCKET nSocket, PSOCKADDR_IN pAddrIn)
: Inherited()
{
SetClientSocket(nSocket, pAddrIn);
m_vFreeList.setLock(&m_vFreeListLock);
}
CCommonServerClient::~CCommonServerClient()
{
}
VOID CCommonServerClient::OnDisconnected()
{
OutputMsg(rmError, _T("%s =%d"), __FUNCTION__);
}
VOID CCommonServerClient::OnError(INT errorCode)
{
OutputMsg(rmError, _T("%s 与[%s][serverindex=%d]的连接错误errcode=%d"),
__FUNCTION__,
getClientName(),
getClientServerIndex(),
errorCode);
}
VOID CCommonServerClient::OnRun()
{
}
VOID CCommonServerClient::OnDispatchRecvPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket)
{
// nCmd ==0 的是心跳包
if (nCmd <= 0)
{
if (nCmd < 0)
OutputMsg(rmWaning, _T("%s recv unknown msg[id=%d]"), __FUNCTION__, (int)nCmd);
return;
}
CDataPacket *outPacket = AllocSendPacket();
if (!outPacket)
{
OutputMsg(rmError, _T("%s Alloc Packet Failed"), __FUNCTION__);
return;
}
// TODO 这里还需要能找到是哪个逻辑服务器发过来的数据。要不然后面逻辑线程处理数据的时候没法释放数据包
// 最好数据包头部加上Client的标记这样就能在逻辑线程处理完数据包的时候正常释放这里分配的数据包对象。
outPacket->writeBuf(inPacket.getOffsetPtr(), inPacket.getAvaliableLength());
GetGlobalLogicEngine()->GetNetWorkHandle()->PostInternalMessage(
SSM_LOGIC_2_COMMONLOGIC_DATA, // 逻辑服务器 -> 公共服务器
nCmd, // 消息ID
(INT_PTR)outPacket, // 消息数据
(UINT_PTR)this); // 用于逻辑线程处理完消息后释放数据包
}
CDataPacket* CCommonServerClient::AllocSendPacket()
{
if (m_vFreeList.count() <= 0)
{
m_vFreeList.flush();
}
if (m_vFreeList.count() <= 0)
{
allocSendPacketList(m_vFreeList,512);
}
CDataPacket* freePacket = m_vFreeList.pop();
freePacket->setLength(0);
return freePacket;
}
void CCommonServerClient::FreeBackUserDataPacket(CDataPacket* pPacket)
{
m_vFreeList.append(pPacket);
}
bool CCommonServerClient::OnValidateRegData(const jxSrvDef::PSERVER_REGDATA pRegData)
{
if (SERVER_REGDATA::GT_JianXiaoJiangHu == pRegData->GameType &&
jxSrvDef::GameServer == pRegData->ServerType)
{
OutputMsg(rmTip, _T("建立同普通逻辑服务器[目标服务器ServerIndex=%d]的连接"), pRegData->ServerIndex);
return true;
}
return false;
}

View File

@@ -0,0 +1,47 @@
#ifndef COMMON_SERVER_CLIENT_H_
#define COMMON_SERVER_CLIENT_H_
/*
公共服务器负责处理和客户端连接的数据发送接受逻辑类。公共辅服务器接受客户端(普通逻辑服务器)
连接后就创建一个CCommonServerClient对象用于和客户端通信。
*/
class CCommonServerClient : public CCustomJXServerClientSocket
{
friend class CCommonServer;
public:
typedef CCustomJXServerClientSocket Inherited;
CCommonServerClient(CCommonServer *lpCommonServer, SOCKET nSocket, PSOCKADDR_IN pAddrIn);
virtual ~CCommonServerClient();
/*
* Comments: 回收空闲的CDataPacket类
* Param CDataPacket * pPacket:
* @Return void:
* @Remark: 收到数据包之后,本地分配数据包对象将内容缓存起来,然后通过逻辑线程处理。
逻辑线程处理完数据后,调用此接口释放数据包对象。
*/
void FreeBackUserDataPacket(CDataPacket* pPacket);
protected:
// CCustomSocket 虚函数
VOID OnDisconnected();
VOID OnError(INT errorCode);
// CCustomWorkSocket 虚函数
VOID OnRun();
// CCustomJXServerClientSocket
VOID OnDispatchRecvPacket(const jxSrvDef::INTERSRVCMD nCmd, CDataPacketReader &inPacket);
bool OnValidateRegData(const jxSrvDef::PSERVER_REGDATA pRegData);
// 由CommonServer调用的例行执行函数
inline VOID Run() { SingleRun(); }
CDataPacket* AllocSendPacket();
private:
CQueueList<CDataPacket*> m_vFreeList; //用来存放空闲的数据包
CCSLock m_vFreeListLock;
};
#endif