GateApp启动流程---rimServer初始化

介绍一下GateApp的启动流程,其实别的进程启动流程也是类似

rimServer.init

首先找到main函数


image.png
image.png

转到run_main看看内容
挑重点讲:


image.png

第一个红框里声明了rimServer对象
然后第二个红框给红框设定配置文件,以及跨服文件
最后一个红框对这个rimServer对象进行初始化

接下来先看看这个rimServer到底是什么东西

进入到engine源码部分:


image.png

直接看这个类的定义


image.png

查看init函数都做了一些什么事情


image.png

直接定位到函数实现
第一个#if 说明了 如果是在linux环境下,在不指定USED_ACE_TRB_PROACTOR的情况下需要执行的代码段,所以这一段内容可以暂时忽略掉
一步一步看执行的函数:

    CTinyXml::initialize();  
image.png

这里不展开说明,实际上是tinyXml的初始化,tinyxml 生成或解析XML非常好用

    CProactor::instance();

在Windows下使用的是Proactor事件模型,进去看看有什么内容


image.png

这个Proactor对象保存了一个单例_instance 如果为NULL 那么new一个CProactor,然后返回这个Proactor对象,看看构造函数的内容:


image.png

上面的代码显示这个成员被初始化了,且这个初始化的类名为CACEProactorImpl,这个Proactor类有两个成员:
image.png

上面图片看看IProactorImpl是什么:


image.png

其实是一个抽象的接口类。那么可以猜到CACEProactorImpl可能是继承了这个接口类。再看看CACEProactorImpl类的声明:
image.png

果不其然,这个接口继承了IProactorImpl,并且自己写了父类的虚函数方法。看看这个类的构造函数都干了一些什么:
image.png

看来在windows平台下,啥也没做,只是在linux平台下初始化了逻辑。先不去管他,暂时只看windows平台下的处理

回到最初


image.png

对Proactor的两个成员变量_instance和变量_IProactorImpl进行一个初始化


image.png

设置日志的初始化
image.png

这段代码首先,它定义了一个 CXml 类型的对象。

接下来,它创建了一个 cdf::COptions 对象,并添加了几个选项。这些选项的名称分别为 "server-config"、"server-name"、"cell-channel"、"copy-channel" 和 "times"。这些选项都需要一个参数(即选项名称后需要提供一个参数值)。

然后,程序调用 options.parse(argc, argv) 来解析命令行参数和选项。这里的 argc 和 argv 是主函数的参数,它们包含了程序启动时传递给程序的所有命令行参数和选项。

接下来,程序检查是否设置了 "server-config" 选项。如果设置了,程序将使用 xml.loadFile 方法加载 options.optArg("server-config").c_str() 所指定的 XML 文件。否则,程序将检查是否设置了 _configFile 变量,如果没有设置,则程序将加载默认的文件 "engine_config.xml"。否则,程序将加载 _configFile 变量指定的文件。解析命令行参数和选项,并根据指定的选项加载一个 XML 文件。

加载完xml文件之后,读取xml对应的配置,对rimServer的成员变量进行赋值


image.png

image.png

_mqThreads :指定线程数量,如果没配置就默认为2个 先不去纠结这是啥,后续再看
_proactorThreads :同上,如果没有配置,就默认为4个
_proactorWaitTime:类似一个等待时间的东西,没设置就默认100
其中rimConfig是一个配置单例类


image.png
image.png

声明了一些参数,这里看个大概就行
xml的文件里也包含了这些值

接下来就是处理跨服文件


image.png

上述代码根据 _crossFile 变量指定的路径加载一个名为 "crossdomain.xml" 的文件。

首先,程序定义了一个 std::ifstream 对象 ifs,这是一个用于从文件中读取数据的输入流对象。

接下来,程序检查 _crossFile 变量是否为空。如果为空,程序将使用 CRMIConfig::instance()->getPath() 方法获取路径并添加文件名 "crossdomain.xml" 来打开文件。否则,程序将使用 _crossFile 变量指定的路径打开文件。

然后,程序检查是否成功打开了文件。如果成功打开了文件,程序将从文件中读取最多 sizeof(buf) 个字节的数据到 buf 中。然后,程序使用 std::string 构造函数将 buf 中的数据转换为一个字符串对象,并将其传递给 CAs3Protocol::setCrossdomain 方法,该方法将字符串保存为一个静态变量。最后,程序使用 CDF_LOG_TRACE 方法记录日志,将读取到的字符串打印出来。

总的来说,这段代码的作用是根据指定的路径加载一个名为 "crossdomain.xml" 的文件,并将其内容保存为一个字符串对象,以便其他部分的程序可以使用。同时,程序还记录了读取到的内容。

其中CAs3Protocol::setCrossdomain 就是对这个类的成员进行赋值,暂时可以不需要知道是干嘛的


image.png
image.png
image.png

这段初始化的核心内容应该就是这段代码了

这段代码的作用是根据 CRMIConfig::instance()->isSingleThread() 的值来创建一个 cdf::CReactor 实例,用于事件驱动程序的反应器模型。

如果 CRMIConfig::instance()->isSingleThread() 的值为真,则程序会使用 USED_ACE_PROACTOR 宏定义编译时选择的 proactor 库,创建一个 cdf::CAceTimerReactorImpl 实例作为反应器模型的实现,并将其包装在 cdf::CReactor 对象中。在创建 cdf::CAceTimerReactorImpl 实例时,程序指定了一个超时等待时间 _proactorWaitTime,一个指向 NULL 的回调函数指针和一个消息队列 cde::CBigMessageQueue::instance()。

否则,如果 CRMIConfig::instance()->isSingleThread() 的值为假,则程序会创建一个不带参数的 cdf::CTimerReactorImpl 实例作为反应器模型的实现,并将其包装在 cdf::CReactor 对象中。

总的来说,这段代码的作用是创建一个事件驱动的反应器模型,并选择合适的反应器实现。这个反应器模型用于处理程序中的异步事件,例如网络 I/O 和定时器超时等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容