OpenRTMFP/Cumulus Primer(4)CumulusServer啟動流程分析
OpenRTMFP/Cumulus Primer(4)CumulusServer啟動流程分析
- 作者:柳大·Poechant(鍾超)
- 部落格:Blog.CSDN.net/Poechant
- 郵箱:zhongchao.ustc#gmail.com (# -> @)
- 日期:April 14th, 2012
首先要知道的是,OpenRTMFP/Cumulus
中使用到的庫有 Poco、OpenSSL 和 Lua。
1 main.cpp 中的 main() 函式
入口在 main.cpp 中:
int main(int argc, char* argv[]) {
先檢查記憶體洩露,不過目前這個開發中的專案還沒有實現這個功能,只是個空函式:
DetectMemoryLeak();
然後會建立一個匿名的 CumulusServer 物件,並呼叫其 run() 函式,該函式由 CumulusServer 從 ServerApplication 中繼承而來,而 ServerApplication 由是從 Application 繼承而來的。CumulusServer 物件呼叫 run() 函式,實際是 ServerApplication 的 run() 函式,ServerApplication 的 run() 函式則是呼叫 Application 的函式,而該 run() 函式則是先呼叫 initialize() 函式,然後呼叫 main() 函式,然後呼叫 uninitialize() 函式。如果 initialize() 函式被呼叫時丟擲異常,則不會執行 main() 函式,但仍然會執行 uninitialize() 函式:
// Runs the application by performing additional initializations
// and calling the main() method.
return CumulusServer().run(argc, argv);
}
2 main.cpp 中的 CumulusServer() 建構函式
CumulusServer 的建構函式定義為:
CumulusServer(): _helpRequested(false), // 顯示幫助資訊
_pCirrus(NULL),
_middle(false),
_isInteractive(true),
_pLogFile(NULL) {
}
3 main.cpp 中的 CumulusServer 的 initialize() 成員函式
在執行 main() 函式之前,CumulusServer 會啟動 initialize() 函式,傳入的引數就是 CumulusServer 自己,可以猜到 Poco::Util::Application 的 run 方法中,呼叫該函式時的引數是this
。
void initialize(Application& self) {
呼叫父函式 ServerApplication 的初始化函式:
ServerApplication::initialize(self);
再繼續下面的原始碼分析之前,先要知道,根據Poco::Util::Application
,Application 類有一些內建的配置屬性,如下:
- application.path: 可執行檔案的絕對路徑;
- application.name: 可執行檔案的檔名(含副檔名);
- application.baseName: 可執行檔案的檔名(不含副檔名)
- application.dir: 可執行檔案的所在目錄;
- application.configDir: 配置檔案所在目錄;
所以下面就讀取了可執行檔案的所在目錄,其中第二個參數列示預設值(即當前目錄):
string dir = config().getString("application.dir", "./");
然後讀取配置檔案,目錄為上一句所得到的dir
,檔名(不含副檔名)為application.basename
內建配置屬性值,其預設值為CumulusServer
,然後加上點和副檔名.ini
。
loadConfiguration(dir
+ config().getString("application.baseName", "CumulusServer")
+ ".ini");
這樣就載入完配置了。然後檢視當前的程式是從命令列執行的(命令列是互動的,所以是 interactive),還是以 daemon 方式執行的,這個函式是ServerApplication
的一個成員函式:
_isInteractive = isInteractive();
然後獲取表示日誌檔案所在目錄的字串,其中logs.directory
是外接配置屬性(配置檔案中),其預設值為上面獲取到的可執行檔案路徑(一般為當前路徑)與logs
的組合,即一般為當前目錄下的logs
目錄:
string logDir(config().getString("logs.directory", dir + "logs"));
建立日誌檔案目錄:
File(logDir).createDirectory();
日誌檔案絕對路徑,logs
為預設的日誌檔名(不含副檔名的部分),副檔名用0
:
_logPath = logDir + "/" + config().getString("logs.name", "log") + ".";
_pLogFile = new File(_logPath + "0");
用日誌流開啟日誌檔案(方式為追加寫入):
_logStream.open(_pLogFile->path(), ios::in | ios::ate);
Logs 是一個方法類(其中的 public 函式都是靜態的),SetLogger
的作用就是將Logs
中的似有靜態成員設定為某個 Cumulus::Logger 物件(由於 CumulusServer 繼承了 Cumulus::Logger)。
Logs::SetLogger(*this);
}
4 main.cpp 中的 CumulusServer 的 main() 成員函式
OpenRTMFP/Cumulus
是一個基於Poco::Util::Application
的服務端應用(準確的說是基於Poco::Util::ServerApplication
的服務端應用)。如果沒有特殊的啟動要求,可以呼叫Poco/Application.h
中定義的巨集POCO_APP_MAIN
來完成初始化、日誌和啟動(該巨集會根據不同的平臺啟用不同的main()
函式)。
run() 函式在呼叫完 initialize() 函式後,會呼叫 CumulusServer 中的 main() 函式,該 main() 函式的定義在 main.cpp 中:
int main(const std::vector<std::string>& args) {
首先看是否是要求幫助資訊,displayHelp
是藉助Poco::Util::HelpFormatter
實現的,CumulusServer
的建構函式會在呼叫時將_helpRequested
設定為false
。
if (_helpRequested) {
displayHelp();
}
如果不是,則進入啟動狀態,首先建立一個RTMFPServerParams
物件params
,用來儲存OpenRTMFP/CumulusServer
的基本配置資訊。
else {
try {
RTMFPServerParams params;
params
儲存CumulusServer
的埠號和CumulusEdge
的埠號:
params.port = config().getInt("port", params.port);
UInt16 edgesPort = config().getInt("edges.port",
RTMFP_DEFAULT_PORT+1);
if(config().getBool("edges.activated",false)) {
if(edgesPort==0)
WARN("edges.port must have a positive value if \
edges.activated is true. Server edges is \
disactivated.");
params.edgesPort=edgesPort;
}
_pCirrus
為SocketAddress
的成員,是封裝IP地址和埠號的物件。
params.pCirrus = _pCirrus;
params.middle = _middle;
UDB 所使用的緩衝區大小:
params.udpBufferSize = config().getInt("udpBufferSize",
params.udpBufferSize);
params.keepAliveServer = config().getInt(
"keepAliveServer",params.keepAliveServer);
params.keepAlivePeer = config().getInt("keepAlivePeer",
params.keepAlivePeer);
失敗前CumulusEdge
的嘗試次數:
params.edgesAttemptsBeforeFallback = config().getInt(
"edges.attemptsBeforeFallback",
params.edgesAttemptsBeforeFallback);
Server server(config().getString("application.dir","./"),
*this,config());
server.start(params);
waitForTerminationRequest()
函式是main()
函式中必須呼叫的,意為等待終止執行的操作請求。
// wait for CTRL-C or kill
waitForTerminationRequest();
一旦接收到終止操作的請求,就會執行下面這句,用以退出OpenRTMFP/Cumulus
的執行:
// Stop the server
server.stop();
catch 一些可能產生的異常:
} catch(Exception& ex) {
FATAL("Configuration problem : %s",ex.displayText().c_str());
} catch (exception& ex) {
FATAL("CumulusServer : %s",ex.what());
} catch (...) {
FATAL("CumulusServer unknown error");
}
}
OpenRTMFP/CumulusServer 停止執行:
return Application::EXIT_OK;
}
-
轉載請註明來自柳大的CSDN部落格:Blog.CSDN.net/Poechant
-
相關文章
- OpenRTMFP/Cumulus Primer(5)CumulusServer啟動流程分析(續)Server
- OpenRTMFP/Cumulus Primer(6)CumulusServer啟動流程分析(續2)Server
- OpenRTMFP/Cumulus Primer(7)CumulusServer啟動流程分析(續3)Server
- OpenRTMFP/Cumulus Primer(5)CumulusServer啟動流程分析(續1)Server
- OpenRTMFP/Cumulus Primer(7)CumulusServer 啟動流程分析(續3)Server
- OpenRTMFP/Cumulus Primer(8)CumulusServer主程式主迴圈分析Server
- OpenRTMFP/Cumulus Primer(1)入門介紹與部署CumulusServerServer
- OpenRTMFP/Cumulus Primer(2)用Lua編寫HelloWorld應用擴充套件CumulusServer套件Server
- OpenRTMFP/Cumulus Primer(16)AMF解析之AMFReader
- OpenRTMFP/Cumulus Primer(14)AMF解析之PacketReader/Writer
- OpenRTMFP/Cumulus Primer(22)執行緒邏輯分析之一:RTMFPServer執行緒的啟動和等待執行緒Server
- OpenRTMFP/Cumulus Primer(18)AMF解析之AMFReader(續2)
- OpenRTMFP/Cumulus Primer(17)AMF解析之AMFReader(續1)
- OpenRTMFP/Cumulus Primer(9)AMF解析之BinaryReader/Writer
- OpenRTMFP/Cumulus Primer(21)經由伺服器的釋出/訂閱流程的關鍵點伺服器
- OpenRTMFP/Cumulus Primer(15)AMF解析之資料型別定義資料型別
- OpenRTMFP/Cumulus Primer(9)AMF 處理方式解析——BinaryReader/Writer
- OpenRTMFP/Cumulus Primer(13)IO管理之區域性記憶體片記憶體
- OpenRTMFP/Cumulus Primer(23)執行緒邏輯分析之二:RTMFPManager對RTMFPServer的影響執行緒Server
- OpenRTMFP/Cumulus Primer(19)獨立使用CumulusLib時的執行緒安全Bug執行緒
- spark core原始碼分析4 worker啟動流程Spark原始碼
- Activity啟動流程分析
- activity 啟動流程分析
- FlutterApp啟動流程分析FlutterAPP
- nodejs啟動流程分析NodeJS
- Flutter啟動流程原始碼分析Flutter原始碼
- Linux:uboot啟動流程分析Linuxboot
- apiserver原始碼分析——啟動流程APIServer原始碼
- Activity啟動流程原始碼分析原始碼
- Android應用啟動流程分析Android
- Flutter系列三:Flutter啟動流程分析Flutter
- Tomcat原始碼分析--啟動流程Tomcat原始碼
- JobTracker啟動流程原始碼級分析原始碼
- 以太坊原始碼分析(39)geth啟動流程分析原始碼
- Android Activity啟動流程原始碼分析Android原始碼
- SpringBoot啟動流程分析原理(一)Spring Boot
- Android原始碼分析:Activity啟動流程Android原始碼
- [譯]Android Application 啟動流程分析AndroidAPP