介紹一下GateApp的啟動流程花盐,其實別的進程啟動流程也是類似
rimServer.init
首先找到main函數(shù)
轉(zhuǎn)到run_main看看內(nèi)容
挑重點講:
第一個紅框里聲明了rimServer對象
然后第二個紅框給紅框設定配置文件蒿褂,以及跨服文件
最后一個紅框?qū)@個rimServer對象進行初始化
接下來先看看這個rimServer到底是什么東西
進入到engine源碼部分:
直接看這個類的定義
查看init函數(shù)都做了一些什么事情
直接定位到函數(shù)實現(xiàn)
第一個#if 說明了 如果是在linux環(huán)境下,在不指定USED_ACE_TRB_PROACTOR的情況下需要執(zhí)行的代碼段卒暂,所以這一段內(nèi)容可以暫時忽略掉
一步一步看執(zhí)行的函數(shù):
CTinyXml::initialize();
這里不展開說明啄栓,實際上是tinyXml的初始化,tinyxml 生成或解析XML非常好用
CProactor::instance();
在Windows下使用的是Proactor事件模型也祠,進去看看有什么內(nèi)容
這個Proactor對象保存了一個單例_instance 如果為NULL 那么new一個CProactor昙楚,然后返回這個Proactor對象,看看構造函數(shù)的內(nèi)容:
上面的代碼顯示這個成員被初始化了诈嘿,且這個初始化的類名為CACEProactorImpl堪旧,這個Proactor類有兩個成員:
上面圖片看看IProactorImpl是什么:
其實是一個抽象的接口類削葱。那么可以猜到CACEProactorImpl可能是繼承了這個接口類。再看看CACEProactorImpl類的聲明:
果不其然淳梦,這個接口繼承了IProactorImpl析砸,并且自己寫了父類的虛函數(shù)方法”郏看看這個類的構造函數(shù)都干了一些什么:
看來在windows平臺下首繁,啥也沒做,只是在linux平臺下初始化了邏輯陨囊。先不去管他弦疮,暫時只看windows平臺下的處理
回到最初
對Proactor的兩個成員變量_instance和變量_IProactorImpl進行一個初始化
設置日志的初始化
這段代碼首先,它定義了一個 CXml 類型的對象蜘醋。
接下來胁塞,它創(chuàng)建了一個 cdf::COptions 對象,并添加了幾個選項压语。這些選項的名稱分別為 "server-config"啸罢、"server-name"、"cell-channel"胎食、"copy-channel" 和 "times"伺糠。這些選項都需要一個參數(shù)(即選項名稱后需要提供一個參數(shù)值)。
然后斥季,程序調(diào)用 options.parse(argc, argv) 來解析命令行參數(shù)和選項训桶。這里的 argc 和 argv 是主函數(shù)的參數(shù),它們包含了程序啟動時傳遞給程序的所有命令行參數(shù)和選項酣倾。
接下來舵揭,程序檢查是否設置了 "server-config" 選項。如果設置了躁锡,程序?qū)⑹褂?xml.loadFile 方法加載 options.optArg("server-config").c_str() 所指定的 XML 文件午绳。否則,程序?qū)z查是否設置了 _configFile 變量映之,如果沒有設置拦焚,則程序?qū)⒓虞d默認的文件 "engine_config.xml"。否則杠输,程序?qū)⒓虞d _configFile 變量指定的文件赎败。解析命令行參數(shù)和選項,并根據(jù)指定的選項加載一個 XML 文件蠢甲。
加載完xml文件之后僵刮,讀取xml對應的配置,對rimServer的成員變量進行賦值
_mqThreads :指定線程數(shù)量,如果沒配置就默認為2個 先不去糾結這是啥搞糕,后續(xù)再看
_proactorThreads :同上勇吊,如果沒有配置,就默認為4個
_proactorWaitTime:類似一個等待時間的東西窍仰,沒設置就默認100
其中rimConfig是一個配置單例類
聲明了一些參數(shù)汉规,這里看個大概就行
xml的文件里也包含了這些值
接下來就是處理跨服文件
上述代碼根據(jù) _crossFile 變量指定的路徑加載一個名為 "crossdomain.xml" 的文件。
首先驹吮,程序定義了一個 std::ifstream 對象 ifs针史,這是一個用于從文件中讀取數(shù)據(jù)的輸入流對象。
接下來钥屈,程序檢查 _crossFile 變量是否為空。如果為空坝辫,程序?qū)⑹褂?CRMIConfig::instance()->getPath() 方法獲取路徑并添加文件名 "crossdomain.xml" 來打開文件篷就。否則,程序?qū)⑹褂?_crossFile 變量指定的路徑打開文件近忙。
然后宦赠,程序檢查是否成功打開了文件整胃。如果成功打開了文件,程序?qū)奈募凶x取最多 sizeof(buf) 個字節(jié)的數(shù)據(jù)到 buf 中。然后丘损,程序使用 std::string 構造函數(shù)將 buf 中的數(shù)據(jù)轉(zhuǎn)換為一個字符串對象,并將其傳遞給 CAs3Protocol::setCrossdomain 方法踏烙,該方法將字符串保存為一個靜態(tài)變量踢涌。最后,程序使用 CDF_LOG_TRACE 方法記錄日志攘残,將讀取到的字符串打印出來拙友。
總的來說,這段代碼的作用是根據(jù)指定的路徑加載一個名為 "crossdomain.xml" 的文件歼郭,并將其內(nèi)容保存為一個字符串對象遗契,以便其他部分的程序可以使用。同時病曾,程序還記錄了讀取到的內(nèi)容牍蜂。
其中CAs3Protocol::setCrossdomain 就是對這個類的成員進行賦值,暫時可以不需要知道是干嘛的
這段初始化的核心內(nèi)容應該就是這段代碼了
這段代碼的作用是根據(jù) CRMIConfig::instance()->isSingleThread() 的值來創(chuàng)建一個 cdf::CReactor 實例泰涂,用于事件驅(qū)動程序的反應器模型鲫竞。
如果 CRMIConfig::instance()->isSingleThread() 的值為真,則程序會使用 USED_ACE_PROACTOR 宏定義編譯時選擇的 proactor 庫逼蒙,創(chuàng)建一個 cdf::CAceTimerReactorImpl 實例作為反應器模型的實現(xiàn)贡茅,并將其包裝在 cdf::CReactor 對象中。在創(chuàng)建 cdf::CAceTimerReactorImpl 實例時,程序指定了一個超時等待時間 _proactorWaitTime顶考,一個指向 NULL 的回調(diào)函數(shù)指針和一個消息隊列 cde::CBigMessageQueue::instance()赁还。
否則,如果 CRMIConfig::instance()->isSingleThread() 的值為假驹沿,則程序會創(chuàng)建一個不帶參數(shù)的 cdf::CTimerReactorImpl 實例作為反應器模型的實現(xiàn)艘策,并將其包裝在 cdf::CReactor 對象中。
總的來說渊季,這段代碼的作用是創(chuàng)建一個事件驅(qū)動的反應器模型朋蔫,并選擇合適的反應器實現(xiàn)。這個反應器模型用于處理程序中的異步事件却汉,例如網(wǎng)絡 I/O 和定時器超時等驯妄。