相关UML:

CAttempterEngine实现了两个接口:IQueueServiceSink、IAttemperEngine;
通过前面的分析,偶们了解到,IQueueServiceSink这个接口被是用来处理CQueueService中的数据的,根据上面的UML我们可以看到,CAttemperEngine关联了一个CQueueService(或者直接点说是:持有了一个CQueueService对象,说组合也成)。这样的话这个CAttemperEngine暴露出来的接口就只剩下IAttemperEnging了。

1 //启动服务
2 virtual bool __cdecl StartService();
3 //停止服务
4 virtual bool __cdecl StopService();
5 //设置网络
6 virtual bool __cdecl SetSocketEngine(IUnknownEx * pIUnknownEx);
7 //注册钩子
8 virtual bool __cdecl SetAttemperEngineSink(IUnknownEx * pIUnknownEx);
9 //获取接口
10 virtual void * __cdecl GetQueueService(const IID & Guid, DWORD dwQueryVer);

这个接口有两处值得单独讨论的:SetSocketEngine、GetQueueService;
SetSocketEngine,后面的分析中还会出现,我觉得这里是一个设计上的失误导致需要暴露socket引擎接口;
GetQueueService的设计思路可能是说,每个IAttemperEngine接口背后都有一个CQueueService,从以后的分析中可以看到,这个思路是理解整个kernel的关键。调度引擎应该是一个消息汇总(从个个引擎产生的消息)然后派发到IAttemperEngineSink。因为代码中是没有看到有关ITimerSink  ISocketSink之类的东东的,,,
整个消息是个引擎产生,然后投递到指定的CQueueService,然后汇总到这里被派发到IAttemperEngineSink出去的,,,

看看CAttemperEngine中处理数据的代码:

 1//队列接口
 2void __cdecl CAttemperEngine::OnQueueServiceSink(WORD wIdentifier, void * pBuffer, WORD wDataSize, DWORD dwInsertTime)
 3{
 4    //内核事件
 5    ASSERT(m_pIAttemperEngineSink!=NULL);
 6    switch (wIdentifier)
 7    {
 8    case EVENT_TIMER:            //定时器事件
 9        {
10            //效验参数
11            ASSERT(wDataSize==sizeof(NTY_TimerEvent));
12            if (wDataSize!=sizeof(NTY_TimerEvent)) return;
13
14            //处理消息
15            NTY_TimerEvent * pTimerEvent=(NTY_TimerEvent *)pBuffer;
16            m_pIAttemperEngineSink->OnEventTimer(pTimerEvent->wTimerID,pTimerEvent->wBindParam);
17
18            return;
19        }
20    case EVENT_DATABASE:        //数据库事件
21        {
22            //效验参数
23            ASSERT(wDataSize>=sizeof(NTY_DataBaseEvent));
24            if (wDataSize<sizeof(NTY_DataBaseEvent)) return;
25
26            //处理消息
27            NTY_DataBaseEvent * pDataBaseEvent=(NTY_DataBaseEvent *)pBuffer;
28            m_pIAttemperEngineSink->OnEventDataBase(pDataBaseEvent+1,wDataSize-sizeof(NTY_DataBaseEvent),pDataBaseEvent);
29
30            return;
31        }
32    case EVENT_SOCKET_ACCEPT:    //网络应答事件
33        {
34            //效验大小
35            ASSERT(wDataSize==sizeof(NTY_SocketAcceptEvent));
36            if (wDataSize!=sizeof(NTY_SocketAcceptEvent)) return;
37
38            //处理消息
39            NTY_SocketAcceptEvent * pSocketAcceptEvent=(NTY_SocketAcceptEvent *)pBuffer;
40            m_pIAttemperEngineSink->OnEventSocketAccept(pSocketAcceptEvent);
41
42            return;
43        }
44    case EVENT_SOCKET_READ:        //网络读取事件
45        {
46            //效验大小
47            NTY_SocketReadEvent * pSocketReadEvent=(NTY_SocketReadEvent *)pBuffer;
48            ASSERT(wDataSize>=sizeof(NTY_SocketReadEvent));
49            ASSERT(wDataSize==(sizeof(NTY_SocketReadEvent)+pSocketReadEvent->wDataSize));
50            if (wDataSize<sizeof(NTY_SocketReadEvent)) return;
51            if (wDataSize!=(sizeof(NTY_SocketReadEvent)+pSocketReadEvent->wDataSize)) return;
52
53            //处理消息
54            bool bSuccess=false;
55            try 
56            { 
57                bSuccess=m_pIAttemperEngineSink->OnEventSocketRead(pSocketReadEvent->Command,pSocketReadEvent+1,pSocketReadEvent->wDataSize,pSocketReadEvent);
58            }
59            catch ()    { }
60            if (bSuccess==false) m_pITCPSocketEngine->CloseSocket(pSocketReadEvent->wIndex,pSocketReadEvent->wRoundID);
61
62            return;
63        }
64    case EVENT_SOCKET_CLOSE:    //网络关闭事件
65        {
66            //效验大小
67            ASSERT(wDataSize==sizeof(NTY_SocketCloseEvent));
68            if (wDataSize!=sizeof(NTY_SocketCloseEvent)) return;
69
70            //处理消息
71            NTY_SocketCloseEvent * pSocketCloseEvent=(NTY_SocketCloseEvent *)pBuffer;
72            m_pIAttemperEngineSink->OnEventSocketClose(pSocketCloseEvent);
73
74            return;
75        }
76    }
77
78    //其他事件
79    m_pIAttemperEngineSink->OnAttemperEvent(wIdentifier,pBuffer,wDataSize,dwInsertTime); 
80
81    return;
82}

这个函数中一个很重要的参数:wIdentifier;
可以来追溯一下他的源头:

 1//数据消息
 2void CQueueService::OnQueueServiceThread(const tagDataHead & DataHead, void * pBuffer, WORD wDataSize)
 3{
 4    ASSERT(m_pIQueueServiceSink!=NULL);
 5    try    
 6    { 
 7        m_pIQueueServiceSink->OnQueueServiceSink(DataHead.wIdentifier,pBuffer,DataHead.wDataSize,DataHead.dwInsertTime); 
 8    }
 9    catch () {}
10    return;
11}

可以看见他是直接保存在最底层的那个DataStroage里边的,这个在上一章分析中可以看到。(个引擎利用CQueueServiceEvent  Post数据的时候就携带了类型信息)

另外一个要注意的点是对socket事件的处理,我之前认为调度引擎组合了一个socket引擎是一个设计缺陷,应为这里的在处理socket read事件的时候如果异常了直接直接使用引擎来关闭socket而不是调用socket sink的指定接口。猜想也许是不希望客户端直接处理socket句柄吧,,,

还是用一句话描述下调度引擎:

调度引擎的工作可以这样描述消息汇总、派发。其他引擎通过CQueueServiceEvent将消息post到调度引擎上来(通过共享同一个CQueueService),然后由调度引擎集中派发出去,,,

转自:http://www.cppblog.com/Error/articles/147948.html

网狐棋牌(三) 调度引擎初步分析相关推荐

  1. 网狐棋牌代码分析(三) 调度引擎初步分析

    (有什么问题欢迎指教,企鹅:2172243813 更多资讯尽在www.ttkmwl.com)    //启动服务 virtual bool__cdecl StartService();     //停 ...

  2. 网狐棋牌(五) TCPSocketEnging分析

    相关UML: 网络引擎整体结构: SocketItem细节: 先来看几个底层结构: //重叠结构类 class COverLapped {     //变量定义 public:     WSABUF  ...

  3. 网狐棋牌(八) 异步引擎 和 网狐棋牌(九) 服务引擎概览

    相关UML: 核心技术在于:在指定的线程中创建窗口,然后向窗口发送消息,在窗口消息处理中调用外部回调. ------------------------------------------------ ...

  4. 网狐棋牌(六) DataBaseEngine 和 网狐棋牌(七) CEventService

    相关UML: 使用数据库引擎必须持有数据库引擎内部队列,实现数据库回调接口(用来处理数据库操作请求),然后结果投递到调度引擎队列. 理解网络狐棋牌,最重要是理解两个概念: 1,队列服务 2,接口的传递 ...

  5. 关于网狐棋牌6603源码的整理、编译和搭建

    最近换工作,趁着有一段清闲时间,整理了一下网狐棋牌的源码,这份源码下载很久了,一直呆在硬盘.这次正好好好看看. 网狐的代码质量很高,流露出来的代码也比较完整,基本上都能编译通过.但是要真的搭建起来,还 ...

  6. 网狐棋牌游戏平台服务器架构设计分析

    调用模型 模仿COM组件接口模式,利用面向对象思想多态性polymorphism,调用方保存着被调用方的基础接口指针(interface or sink钩子)(Pure Virtual Functio ...

  7. 网狐棋牌游戏平台服务器架构设计分析[转]

    网狐棋牌游戏平台服务器架构设计分析[转] http://blog.csdn.net/weiwangchao_/article/details/7047044 基本设计概念和处理流程 调用模型 模仿CO ...

  8. 网狐棋牌经典版管理后台操作手册

    网狐棋牌_经典版游戏 管理后台操作手册                                   管理平台概述: i.             使用说明: 本手册是提供给运营商阅读使用,帮助 ...

  9. 网狐卓越版本内核引擎、卓越内核(源码,源码,源码)

    经过一段时间折腾,终于搞定网狐卓越版本内核引擎.源码,源码,源码. 话不多说,先上图. 代码截图 编译成功 运行效果图 下面来介绍逆向过程. 查看网狐给的头文件 KernelEngineHead.h. ...

最新文章

  1. 剑指offer 刷题 01
  2. 自学python还是报班-学习Python到底是培训还是自学合适呢?
  3. Oracle的ERP费用,Oracle ERP费用云
  4. 存定期还能加钱进去吗_很多人说傻子才存钱,在银行存定期还有必要吗?
  5. php 如何获取表格数据类型,使用phpword获取doc中的表格数据
  6. maccmsv10 苹果cms 深度定制站群版
  7. java 一个大事务下的新增、修改、查询_一文带你轻松搞懂事务隔离级别(图文详解)...
  8. ROS中阶笔记(五):机器人感知—机器视觉
  9. Scala学习(一):Scala简介与Hello World!
  10. 软考(6)--数据库
  11. 2021SC@SDUSC——使用CUDA/GPU技术加速密码运算(一)
  12. EMC理论基础知识——电磁屏蔽
  13. matlab代码:考虑实时市场联动的电力零售商鲁棒定价策略
  14. Angular 数据循环
  15. 多元线性回归分析理论详解及SPSS结果分析
  16. 【解的封闭形式】Abel-Ruffini theorem(阿贝尔-鲁菲尼定理)
  17. 推荐10个关键时刻能派上大用场的神级软件,帮你解决80%的问题
  18. 蒋涛:区块链技术将推动生产力与生产关系的革新
  19. 马斯洛人类需求五层次理论(Maslow's Hierarchy of Needs)
  20. pip3 install pymysql

热门文章

  1. POI的入门:创建单元格设置数据
  2. FastDFS在项目中的应用
  3. mybatis-plus根据多个字段排序_Mybatis Plus学习笔记(逻辑删除/动态填充/常用插件)...
  4. vue中的provide/inject的学习
  5. java并发编程学习5--forkJoin
  6. Linux文件系统之swap
  7. Python format() 函数
  8. Lua_第17 章 数学库
  9. 《UCD火花集2:有效的互联网产品设计 交互/信息设计 用户研究讨论》一2.3 交互设计师容易犯的错误:把自己禁锢在解决方案之中...
  10. 代理服务器https协议单站点开通注意事项