Files
mir_server/sdk/commonLib/include/CustomServerGate.h

303 lines
14 KiB
C
Raw Permalink Normal View History

2025-01-09 17:45:40 +08:00
#ifndef _CUSTOM_SERVER_GATE_H_
#define _CUSTOM_SERVER_GATE_H_
#include"Define.h"
class CCustomGateManager;
class CCustomServerGateUser;
/*******************************************************
*
*
*
* 使使
*
*
********************************************************/
/* ★ 定义_USE_GATE_SEND_PACK_LIST_宏将使用发送列表来处理发送数据包
使
使
使
使_USE_GATE_SEND_PACK_LIST_宏来使用发送列表时
1 线使
AllocGateSendPacketList一次性申请多个发送数据包
FlushGateSendPacketList一次性全部提交一个
/
/
使
0FlushGateSendPacketList函数不会修改提交数据包列表
GATEMSGHDR
2 /
/
使
GATEMSGHDR
*/
#define _USE_GATE_SEND_PACK_LIST_
using namespace wylib::time::tick64;
using namespace wylib::container;
class CCustomServerGate
: public CCustomServerClientSocketEx
{
friend class CCustomGateManager;
public:
typedef CCustomServerClientSocket Inherited;
public:
#ifndef _USE_GATE_SEND_PACK_LIST_
/* 添加向网关发送的数据,数据必须包含了网关通信协议头 */
VOID AddGateBuffer(LPCVOID pBuffer, SIZE_T nBufferSize);
/* 添加向网关发送的用户数据,数据为不包含网关通信协议头的,函数会自动追加网关通信协议头
* pUser
* nGateSessionIndex
*/
VOID AddUserBuffer(UINT64 nUserSocket, INT_PTR nGateSessionIndex, LPCVOID pBuffer, SIZE_T nBufferSize);
#else
/* 申请一份发送数据包
* GATEMSGHDR
* 使sizeof(GATEMSGHDR)
* 使
* FlushSendPacket提交发送数据
*
* nUserSocket
* nGateSessionIndex
*/
CDataPacket& AllocGateSendPacket(UINT64 nUserSocket, int nGateSessionIndex,int nServerIndex =0);
/* 提交一份数据包到发送队列中
*
*/
VOID FlushGateSendPacket(CDataPacket& packet);
//发送一个连串的数据包
VOID FlushGateBigPacket(CDataPacket& packet);
/* 申请一批发送数据包
* FlushSendPacket提交单个数据包或FlushSendPacketList提交多个数据包到发送队列
* attention
*
* 使
* GATEMSGHDR
*
*
* packetList
* nAllocCount
* ppSingleAlloc nAllocCount+1nAllocCount
* nAllocCount中并单独向*ppSingleAlloc中保存一个
*/
inline VOID AllocGateSendPacketList(CBaseList<CDataPacket*>& packetList, INT_PTR nAllocCount)
{
allocSendPacketList(packetList, nAllocCount);
}
/* 提交一批发送数据包
* attention
* 0
*
* GATEMSGHDR
*
*
* packetList
* nAllocCount
*/
inline VOID FlushGateSendPacketList(CBaseList<CDataPacket*>& packetList)
{
flushSendPacketList(packetList);
}
#endif
/* 投递关闭网关用户的消息
* nSocket对应的用户
* 线
*
*
*/
inline VOID PostCloseUser(UINT64 nUserSocket)
{
PostInternalMessage(SGIM_CLOSE_USER_SOCKET, (UINT_PTR)nUserSocket, 0, 0);
}
/* 投递关闭网关用户的消息
*
* 线
*
*
*/
inline VOID PostCloseUser(UINT64 nUserSocket, int nServerSessionIndex)
{
PostInternalMessage(SGIM_CLOSE_USER_SOCKET_SIDX, (UINT_PTR)nUserSocket, nServerSessionIndex, 0);
}
/*
* Comments:
* ID关闭网关用户
* ID关闭用户nSessionID对应的用户
* 线
*
*
*
* Param const int nSessionID:id
* @Return VOID:
*/
inline VOID PostCloseUserByGlobalSessionId(const int nSessionID)
{
PostInternalMessage(SGIM_CLOSE_USER_SOCKET_GSID, nSessionID,0, 0);
}
/*
* Comments:线
* Param const int nSessionID:di
* @Return VOID:
*/
inline VOID PostKickUserByGlobalSessionId(const int nSessionID)
{
PostInternalMessage(SGIM_KICK_USER_SOCKET_GSID, nSessionID,0, 0);
}
/* 获取网关名称 */
inline LPCSTR getGateName(){ return m_sGateName; }
/* 获取网关编号 */
inline INT_PTR getGateIndex(){ return m_nGateIndex; }
// 获取网关用户信息
inline GATEUSERINFO getGateUserInfo() { return m_GateUserInfo; }
protected:
/*** 本protected函数集为子类的逻辑处理有必要覆盖的函数集 ***/
/* ★创建网关用户对象默认的返回值是new一个CCustomGateUser的实例 */
virtual CCustomServerGateUser* CreateGateUser();
/* ★销毁网关用户对象默认的操作是delete此对象 */
virtual VOID DestroyGateUser(CCustomServerGateUser* pUser);
/* ★当一个用户连接后回调此函数 */
virtual VOID OnOpenUser(CCustomServerGateUser *pUser);
/* ★当一个网关用户关闭时回调此函数 */
virtual VOID OnCloseUser(CCustomServerGateUser *pUser);
/* ★当网关连接断开时调用此函数 */
virtual VOID OnGateClosed();
/* ★当需要处理网关转发给用户的一个完整的通信包时调用
*pUser
*pBuffer
*/
virtual VOID OnDispatchUserMsg(CCustomServerGateUser *pUser, char* pBuffer, SIZE_T nBufferSize) = 0;
//关闭会话
virtual VOID KickUserByGlobalSessionId(const int nGlobalSessionId);
protected:
//处理网关套接字错误
VOID SocketError(INT nErrorCode);
//处理网关连接断开
VOID Disconnected();
//当长时间没有通信后发送保持连接的消息
VOID SendKeepAlive();
//处理接受到的服务器数据包
VOID ProcessRecvBuffers(PDATABUFFER pDataBuffer);
//VOID DispatchInternalMessage(UINT uMsg, UINT_PTR uParam1, UINT_PTR uParam2, UINT_PTR uParam3,UINT_PTR uParam4=0);
//进行内部消息的处理分派
virtual VOID DispatchInternalMessage(UINT uMsg, UINT64 uParam1, UINT64 uParam2, UINT64 uParam3,UINT64 uParam4);
//分派网关接收到的数据
VOID DispathRecvMessage(PGATEMSGHDR pMsgHdr, char *pBuffer, SIZE_T nBufSize);
//每次逻辑循环的例行逻辑处理函数,将实现数据缓冲中的数据发送到网关的功能
VOID SingleRun();
protected:
/*打开新用户
*nSocket
*nSessionIndex
*sIPAddr IP地址字符串
*/
INT_PTR OpenNewUser(UINT64 nSocket, int nGateSessionIndex, char *sIPAddr);
/*
* Comments:nSocket对应的用户
* Param const UINT64 nSocket: socketID
* Param bool bNeedTellGate: true
* @Return VOID:
*/
VOID CloseUser(const UINT64 nSocket,bool bNeedTellGate=true);
/* 依据套接字句柄以及用户在服务器的索引关闭用户,效率很快 */
VOID CloseUser(const UINT64 nSocket, const int nServerSessionIndex,bool bNeedTellGate=true);
/* 依据全局会话ID关闭用户效率很慢需要遍历查找与nSessionId对应的用户 */
VOID CloseUserByGlobalSessionId(const int nGlobalSessionId);
/* 依据全局会话ID查找网关用户对象效率很慢需要遍历查找与nSessionId对应的用户
*pIndex
*/
CCustomServerGateUser* UserExistsOfGlobalSessionId(const int nGlobalSessionId, PINT_PTR pIndex);
/* 关闭所有用户 */
VOID CloseAllUser();
/* 将网关转发的用户数据发送给用户 */
VOID PostUserData(PGATEMSGHDR pMsgHdr, char *pData, SIZE_T nDataSize);
//关闭网关连接的程序
VOID PostCloseGateServer();
#ifndef _USE_GATE_SEND_PACK_LIST_
/* 将发送缓冲中的数据发送到网关中 */
VOID SendGateBuffers();
#endif
/* 处理关闭网关用户的事宜 */
VOID GateUserClosed(CCustomServerGateUser *pGateUser,bool bNeedTellGate =true);
/* 向网关发送关闭用户的消息 */
VOID SendGateCloseUser(UINT64 nSocket, int nGateSessionIndex,int nServerIndex);
/* 向网关发送新用户在本网关中被分配的会话索引 */
VOID SendAcceptUser(UINT64 nSocket, int nGateSessionIndex, int nServerSessionIndex);
/* 释放各个缓冲区内存 */
VOID FreeBuffers();
public:
CCustomServerGate();
~CCustomServerGate();
private:
CHAR m_sGateName[32]; //网关名称
#ifndef _USE_GATE_SEND_PACK_LIST_
DATABUFFER m_SendBufQueue[2]; //两个数据缓冲区,当发送缓冲区为空则交换发送和追加缓冲区
PDATABUFFER m_pSendAppendBuffer; //当前正在追加的管道数据缓冲区指针
PDATABUFFER m_pSendProcBuffer; //当前正在写入管道的数据缓冲区指针
CRITICAL_SECTION m_WriteLock; //数据写入锁
#endif
protected:
INT_PTR m_nGateIndex; //网关编号
CBaseList<CCustomServerGateUser*> m_UserList; //用户列表
bool m_bHasPrintErrInfo; // 是否已经输出了错误信息(为降低性能开销,只输出一次)
GATEUSERINFO m_GateUserInfo; // 网关用户信息
private:
/*
* 线
*
*/
//按用户SOCKET关闭用户,Param1 = Socket
static const UINT SGIM_CLOSE_USER_SOCKET = 101;
//按用户SOCKET以及用户在服务器中的会话编号关闭用户Param1=Socket, Param2=ServerSessionIndex
static const UINT SGIM_CLOSE_USER_SOCKET_SIDX = 102;
//按用户的全局会话ID关闭用户Param1=全局会话ID
static const UINT SGIM_CLOSE_USER_SOCKET_GSID = 103;
//会话踢人下线在跨服处理的时候和103有点差别
static const UINT SGIM_KICK_USER_SOCKET_GSID = 104;
};
#endif