kbengine源代码读v0.0.1

上传人:平*** 文档编号:15393905 上传时间:2017-11-04 格式:DOCX 页数:19 大小:65.48KB
返回 下载 相关 举报
kbengine源代码读v0.0.1_第1页
第1页 / 共19页
kbengine源代码读v0.0.1_第2页
第2页 / 共19页
kbengine源代码读v0.0.1_第3页
第3页 / 共19页
kbengine源代码读v0.0.1_第4页
第4页 / 共19页
kbengine源代码读v0.0.1_第5页
第5页 / 共19页
点击查看更多>>
资源描述

《kbengine源代码读v0.0.1》由会员分享,可在线阅读,更多相关《kbengine源代码读v0.0.1(19页珍藏版)》请在金锄头文库上搜索。

1、基于 kbengine 0.4.20MMOG 服务端是一种高品质的工程项目,品读开源的 kbe 是一种乐趣。本文档我带童鞋们一起领略一下。囿于我知识面和经验方面所限,文中所述之处难免有错误存在,还请读童鞋们睁大慧眼,如果你发现错误,可以 电邮至 。 (因为我个人懒散或者时间仓促的关系,这个文档的排版有点小乱。 。 。 )其他牛逼哄哄的前言就不说了。从理论上来讲,我们阅读一份源代码,首先应该基于现有的文档从整体上把握项目的架构之后再庖丁解牛一般地细分阅读,不过在我写这个文档的现在,我暂时没发现这样的文档,所以我就按照我自己的阅读顺序从而编排这个文档的内容。从已有的文档可知(我得假设你已经大致看完

2、了 kbe 官网的现有文档) ,kbe 由几个组件共同协作,所以我们先看看组件们:各个组件被设计为独立的 app,使用网络通信进行协作。C+ 程序自然是从 main 函数开始。看起来似乎所有的组件都有一个这样的宏(KBENGINE_MAIN)来包裹 main 函数int KBENGINE_MAIN(int argc, char* argv)ENGINE_COMPONENT_INFO& info = g_kbeSrvConfig.getXXX();return kbeMainT(argc, argv, YYY, info.externalPorts_min, info.externalPorts

3、_max, info.externalInterface, 0, info.internalInterface);这个宏展开是这样子:kbeMain(int argc, char* argv);int main(int argc, char* argv)loadConfig();g_componentID = genUUID64();parseMainCommandArgs(argc, argv);char dumpnameMAX_BUF = 0;kbe_snprintf(dumpname, MAX_BUF, %PRAppID, g_componentID);KBEngine:exceptio

4、n:installCrashHandler(1, dumpname);int retcode = -1;THREAD_TRY_EXECUTION;retcode = kbeMain(argc, argv);THREAD_HANDLE_CRASH;return retcode;稍微整理一下之后很像是这个样子:int kbeMain(int argc, char* argv);int main(int argc, char* argv)loadConfig();g_componentID = genUUID64();parseMainCommandArgs(argc, argv);char dum

5、pnameMAX_BUF = 0;kbe_snprintf(dumpname, MAX_BUF, %PRAppID, g_componentID);KBEngine:exception:installCrashHandler(1, dumpname);int retcode = -1;THREAD_TRY_EXECUTION;retcode = kbeMain(argc, argv);THREAD_HANDLE_CRASH;return (retcode);int kbeMain(int argc, char* argv)ENGINE_COMPONENT_INFO& info = g_kbeS

6、rvConfig.getXXX();return kbeMainT(argc, argv, YYY, info.externalPorts_min, info.externalPorts_max, info.externalInterface, 0, info.internalInterface);嗯。 。 。基本可以理解为每个组件的main函数流程都是一样的,只是在特化kbeMainT时所给参数不一样。我们跟着main 函数的 loadConfig进去看看(kbemain.h)inline void loadConfig()Resmgr:getSingleton().initialize()

7、;/ ././res/server/kbengine_defs.xmlg_kbeSrvConfig.loadConfig(server/kbengine_defs.xml);/ ./././assets/res/server/kbengine.xmlg_kbeSrvConfig.loadConfig(server/kbengine.xml);在serverconfig.h中可以看到这样的代码:#define g_kbeSrvConfig ServerConfig:getSingleton()Resmgr和ServerConfig,这两个类都是被搞成单例了的(kbe的单例不算太严格的单例,线程安

8、全,编译时阻断都无法满足,我们先不细究) ,Resmgr是资源管理器,在resmgr.h/.cpp中声明和定义,在FixedMessages 类(fixed_messages.h/.cpp)的构造函数中被new出来。 (有点小隐晦,我是调试了一下才跟到的。 。 ) 过程是这样,在各个组件的xxx_interface.cpp中,有这样的代码:(摘自loginapp)#include loginapp_interface.h#define DEFINE_IN_INTERFACE#define LOGINAPP#include loginapp_interface.hxxx_interface.h中

9、,有这样的代码:#if defined(DEFINE_IN_INTERFACE)#undef KBE_LOGINAPP_INTERFACE_H#endif#ifndef KBE_LOGINAPP_INTERFACE_H#define KBE_LOGINAPP_INTERFACE_H大意可以理解为在xxx_interface.cpp中通过在包含xxx_interface.h前后定义DEFINE_IN_INTERFACE和LOGINAPP宏,使得xxx_interface.h被包含了两次(但产生的代码确实不同的) ,从而对xxx_interface.h内的一些变量实现了声明(第一次)和定义(第二次

10、) 。在xxx_interface.h中有这样一句:NETWORK_INTERFACE_DECLARE_BEGIN(LoginappInterface)展开就是:/ 定义接口域名称#ifndef DEFINE_IN_INTERFACE#define NETWORK_INTERFACE_DECLARE_BEGIN(INAME) namespace INAME extern Network:MessageHandlers messageHandlers; #else#define NETWORK_INTERFACE_DECLARE_BEGIN(INAME) namespace INAME Netw

11、ork:MessageHandlers messageHandlers; #endif#define NETWORK_INTERFACE_DECLARE_END() 在第一次包含xxx_interface.h的时候就是extern Network.这样的外部全局变量引用声明,第二次包含的时候就是Network:M.这样的全局变量的定义了。在Network:MessageHandles的构造函数 (message_handler.cpp)中,有:MessageHandlers:MessageHandlers():msgHandlers_(),msgID_(1),exposedMessages_(

12、)g_fm = Network:FixedMessages:getSingletonPtr();if(g_fm = NULL)g_fm = new Network:FixedMessages;Network:FixedMessages:getSingleton().loadConfig(server/messages_fixed.xml);messageHandlers().push_back(this);至此,Network:FixedMessages类被有机会实例化,构造函数中有:FixedMessages:FixedMessages():_infomap(),_loaded(false)

13、new Resmgr();Resmgr:getSingleton().initialize();ServerConfig在各个组件(比如loginapp在loginapp.cpp)的类的定义文件中实例化。ServerConfig g_serverConfig;KBE_SINGLETON_INIT(Loginapp);我们再次回到loadConfig ,里面的函数小跟一下就能读明白了,我们继续跟进主干流程。下面的语句给组件生成一个随机idg_componentID = genUUID64();下面的语句解析主函数的参数:(比如设定指定的组件id,以及gus,我也还没了解到gus搞啥用的。 。 。

14、不影响我们阅读整体流程,不细究)parseMainCommandArgs(argc, argv);下面的语句进行crash处理:(不影响我们阅读整体流程,不细究)char dumpnameMAX_BUF = 0;kbe_snprintf(dumpname, MAX_BUF, %PRAppID, g_componentID);KBEngine:exception:installCrashHandler(1, dumpname);下面的语句就是一个标准的main函数转向:int retcode = -1;THREAD_TRY_EXECUTION;retcode = kbeMain(argc, ar

15、gv);THREAD_HANDLE_CRASH;return retcode;在kbemain.h中可以看到KBENGINE_MAIN针对不同的平台有不同的定义。 。 。其实就是非win32平台没有crash处理。kbeMain是在各个组件的 main.cpp中定义的:(摘自loginapp)ENGINE_COMPONENT_INFO& info = g_kbeSrvConfig.getLoginApp();return kbeMainT(argc, argv, LOGINAPP_TYPE, info.externalPorts_min, info.externalPorts_max, inf

16、o.externalInterface, 0, info.internalInterface);第一句就是获取到各个组件相关的信息,然后流程再次转向,到了kbeMainT函数。kbeMainT是一个模板函数,根据各个组件的主类的不同,产生不同的代码(。 。 。我是不是有点过了)前面的一些语句我们暂且不看(后面会需要看的) ,有设置环境变量的,设置密钥对的。可以看到kbeMainT的流程以各个组件的实例的run接口而终止。大致看了几个组件的run函数,有的是调用 ServerApp的run接口,有的是直接调用dispatcher的processXXX接口,总的来讲,就是依靠事件派发器来进行工作了。所以我们有必要去看看kbe的事件派发器了。 loginapp组

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号