相关UML:

代码分析:
首先CQueueServiceEvent这个名字很有诱惑,,,你感觉他是一个事件,其实不是。它实际的功能应该是一个带打包功能的事件队列,,,或者说是一个像指定的类似EventQueue的东东中投递事件。从接口上看,这个东东能投递TimerEvent DataBaseEvent SocketAcceptEvent SocketReadEvent SocketCloseEvent
应为它本身持有一个CQueueService指针,所以本身并不负责数据管理,只负责打包并添加到CQueueService实例中去。
先看定时器事件:
入口都有断言在debug阶段帮助暴露错误,断言之后还有if语句再次判断,这样即使release版本错误也不会被漏掉,,,
关于事件的封装,在这里其实已经分层了,,,
这里是第一层:
在来看Post这一层做的数据打包:
其他事件的打包过程都是类似的:
还是一样,一句话总结CQueueServiceEvent:

代码分析:
首先CQueueServiceEvent这个名字很有诱惑,,,你感觉他是一个事件,其实不是。它实际的功能应该是一个带打包功能的事件队列,,,或者说是一个像指定的类似EventQueue的东东中投递事件。从接口上看,这个东东能投递TimerEvent DataBaseEvent SocketAcceptEvent SocketReadEvent SocketCloseEvent
应为它本身持有一个CQueueService指针,所以本身并不负责数据管理,只负责打包并添加到CQueueService实例中去。
先看定时器事件:
1
//定时器事件
2
bool PostTimerEvent(WORD wTimerID, WPARAM wBindParam)
3
{
4
//效验参数
5
ASSERT(m_pIQueueService!=NULL);
6
if (m_pIQueueService==NULL) return false;
7
8
//缓冲锁定
9
CThreadLockHandle BufferLockHandle(&m_BufferLock);
10
11
//投递消息
12
NTY_TimerEvent * pTimerEvent=(NTY_TimerEvent *)m_cbBuffer;
13
pTimerEvent->wTimerID=wTimerID;
14
pTimerEvent->wBindParam=wBindParam;
15
m_pIQueueService->AddToQueue(EVENT_TIMER,m_cbBuffer,sizeof(NTY_TimerEvent));
16
17
return true;
18
}
嗯哼,代码质量很高哈,,,
//定时器事件2
bool PostTimerEvent(WORD wTimerID, WPARAM wBindParam)3
{4
//效验参数5
ASSERT(m_pIQueueService!=NULL);6
if (m_pIQueueService==NULL) return false;7

8
//缓冲锁定9
CThreadLockHandle BufferLockHandle(&m_BufferLock);10

11
//投递消息12
NTY_TimerEvent * pTimerEvent=(NTY_TimerEvent *)m_cbBuffer;13
pTimerEvent->wTimerID=wTimerID;14
pTimerEvent->wBindParam=wBindParam;15
m_pIQueueService->AddToQueue(EVENT_TIMER,m_cbBuffer,sizeof(NTY_TimerEvent));16

17
return true;18
}
入口都有断言在debug阶段帮助暴露错误,断言之后还有if语句再次判断,这样即使release版本错误也不会被漏掉,,,
关于事件的封装,在这里其实已经分层了,,,
这里是第一层:
1
struct tagDataHead
2
{
3
WORD wDataSize; //数据大小
4
WORD wIdentifier; //类型标识
5
DWORD dwInsertTime; //插入时间
6
};
这一层实际上是由CDataStorage负责打包管理,在CQueueServiceEvent执行PostTimerEvent操作的时候会在内部调用CQueueService的add最终调用到CDataStrorage的Add来打包数据,这里的结构也是非常像网络数据包|- len -|- type -|- data -|。
struct tagDataHead2
{3
WORD wDataSize; //数据大小4
WORD wIdentifier; //类型标识5
DWORD dwInsertTime; //插入时间6
};
在来看Post这一层做的数据打包:
1
//定时器事件
2
struct NTY_TimerEvent
3
{
4
WORD wTimerID; //定时器 ID
5
WPARAM wBindParam; //绑定参数
6
};
|- len -|- type -|- sub protocl -|。
//定时器事件2
struct NTY_TimerEvent3
{4
WORD wTimerID; //定时器 ID5
WPARAM wBindParam; //绑定参数6
};
其他事件的打包过程都是类似的:
1
//数据库请求事件
2
struct NTY_DataBaseEvent
3
{
4
WORD wIndex; //对象索引
5
WORD wRoundID; //对象标识
6
WORD wRequestID; //请求标识
7
};
8
9
//网络应答事件
10
struct NTY_SocketAcceptEvent
11
{
12
WORD wIndex; //连接索引
13
WORD wRoundID; //连接标识
14
DWORD dwClientIP; //连接地址
15
};
16
17
//网络读取事件
18
struct NTY_SocketReadEvent
19
{
20
WORD wIndex; //连接索引
21
WORD wRoundID; //连接标识
22
WORD wDataSize; //数据大小
23
CMD_Command Command; //命令信息
24
};
25
26
//网络关闭事件
27
struct NTY_SocketCloseEvent
28
{
29
WORD wIndex; //连接索引
30
WORD wRoundID; //连接标识
31
DWORD dwClientIP; //连接地址
32
DWORD dwConnectSecond; //连接时间
33
};
//数据库请求事件2
struct NTY_DataBaseEvent3
{4
WORD wIndex; //对象索引5
WORD wRoundID; //对象标识6
WORD wRequestID; //请求标识7
};8

9
//网络应答事件10
struct NTY_SocketAcceptEvent11
{12
WORD wIndex; //连接索引13
WORD wRoundID; //连接标识14
DWORD dwClientIP; //连接地址15
};16

17
//网络读取事件18
struct NTY_SocketReadEvent19
{20
WORD wIndex; //连接索引21
WORD wRoundID; //连接标识22
WORD wDataSize; //数据大小23
CMD_Command Command; //命令信息24
};25

26
//网络关闭事件27
struct NTY_SocketCloseEvent28
{29
WORD wIndex; //连接索引30
WORD wRoundID; //连接标识31
DWORD dwClientIP; //连接地址32
DWORD dwConnectSecond; //连接时间33
};
还是一样,一句话总结CQueueServiceEvent:
线程安全的接受各种异步事件,并打包封装好以后插入到关联的制定IQueueService中.
本文深入剖析了CQueueServiceEvent的实现细节,揭示其如何通过分层结构进行事件的高效打包与封装,确保线程安全地处理各种异步事件。从定时器事件到数据库请求事件,再到网络相关的多种事件类型,CQueueServiceEvent通过精心设计的数据结构和方法实现了事件的统一管理与传递。
6689

被折叠的 条评论
为什么被折叠?



