从Main函数开始认识cRtmpServer (2)

在cRtmpServer的入口处,有三个函数比较重要:

一,main()函数,这是整个cRtmpServer服务的入口函数;检查命令行参数及启动其它两个函数;

int main(int argc, char **argv) 
{
	SRAND();
	InitNetworking();

	//1. Pick up the startup parameters and hold them inside the running status
	if (argc < 2) {
		cout << "Invalid command line. Use --help" << endl;
		return -1;
	}

	//命令行参数检查;
	if (!Variant::DeserializeFromCmdLineArgs(argc, argv, gRs.commandLine)) 
	{			
		PrintHelp();
		return -1;
	}
	string configFile = argv[argc - 1];
	if (configFile.find("--") == 0)
		configFile = "";
	NormalizeCommandLine(configFile);

	if ((bool)gRs.commandLine["arguments"]["--help"]) 
	{
		PrintHelp();
		return 0;
	}

	if ((bool)gRs.commandLine["arguments"]["--version"]) 
	{
		PrintVersion();
		return 0;
	}

	do 
	{
		//2. Reset the run flag
		gRs.run = false;

		//3. Initialize the running status
		if (Initialize()) 
		{											//初始化整个流媒体服务器;
			Run();									//处理各种事件;
		} else 
		{
			gRs.run = false;
		}

		//5. Cleanup
		Cleanup();									//关闭服务器的各项功能,并清空;
	} while (gRs.run);

	//6. We are done
	return 0;
}

二,Initialize函数;

bool Initialize() {
	Logger::Init();

	if ((bool)gRs.commandLine["arguments"]["--use-implicit-console-appender"]) {
		Variant dummy;
		dummy[CONF_LOG_APPENDER_NAME] = "implicit console appender";
		dummy[CONF_LOG_APPENDER_TYPE] = CONF_LOG_APPENDER_TYPE_CONSOLE;
		dummy[CONF_LOG_APPENDER_COLORED] = (bool)true;
		dummy[CONF_LOG_APPENDER_LEVEL] = (uint32_t) 6;
		ConsoleLogLocation * pLogLocation = new ConsoleLogLocation(dummy);
		pLogLocation->SetLevel(_FINEST_);
		Logger::AddLogLocation(pLogLocation);
	}

	INFO("Reading configuration from %s", STR(gRs.commandLine["arguments"]["configFile"]));
#ifdef COMPILE_STATIC
	gRs.pConfigFile = new ConfigFile(SpawnApplication, SpawnFactory);
#else
	gRs.pConfigFile = new ConfigFile(NULL, NULL);
#endif
	string configFilePath = gRs.commandLine["arguments"]["configFile"];
	string fileName;
	string extension;
	splitFileName(configFilePath, fileName, extension);

	if (lowerCase(extension) == "xml") {
		if (!gRs.pConfigFile->LoadXmlFile(configFilePath,
				(bool)gRs.commandLine["arguments"]["--daemon"])) {
			FATAL("Unable to load file %s", STR(configFilePath));
			return false;
		}
	} else if (lowerCase(extension) == "lua") {
#ifdef HAS_LUA
		if (!gRs.pConfigFile->LoadLuaFile(configFilePath,
				(bool)gRs.commandLine["arguments"]["--daemon"])) {
			FATAL("Unable to load file %s", STR(configFilePath));
			return false;
		}
#else
		cout << "Lua is not supported by the current build of the server" << endl;
		ASSERT("Lua is not supported by the current build of the server");
		return false;
#endif /* HAS_LUA */
	} else {
		FATAL("Invalid file format: %s", STR(configFilePath));
		return false;
	}

#ifndef WIN32
	if (gRs.pConfigFile->IsDaemon()) {
		if (!gRs.daemon) {
			INFO("Daemonize...");
			pid_t pid = fork();
			if (pid < 0) {
				FATAL("Unable to start daemonize. fork() failed");
				return false;
			}

			if (pid > 0) {
				if (gRs.commandLine["arguments"].HasKey("--pid"))
					WritePidFile(pid);
				return false;
			}

			FINEST("Create a new SID for the daemon");
			pid_t sid = setsid();
			if (sid < 0) {
				FATAL("Unable to start daemonize. setsid() failed");
				return false;
			}

			gRs.daemon = true;
			
			Logger::SignalFork();
		}
	}
#endif /* WIN32 */

	INFO("Configure logger");
	if (!gRs.pConfigFile->ConfigLogAppenders()) {			//配置流媒体服务器日志模块;
		FATAL("Unable to configure log appenders");
		return false;
	}

	INFO("Initialize I/O handlers manager: %s", NETWORK_REACTOR);
	IOHandlerManager::Initialize();							//初始化类IOHandlerManager的成员变量;

	INFO("Configure modules");
	if (!gRs.pConfigFile->ConfigModules()) {				//加载各个模块的动态库;
		FATAL("Unable to configure modules");
		return false;
	}

	INFO("Plug in the default protocol factory");
	gRs.pProtocolFactory = new DefaultProtocolFactory();	//创建类DefaultProtocolFactory的对象;
	if (!ProtocolFactoryManager::RegisterProtocolFactory(gRs.pProtocolFactory)) {  //初始化协议工厂类的对象的成员变量;
		FATAL("Unable to register default protocols factory");
		return false;
	}

	INFO("Configure factories");
	if (!gRs.pConfigFile->ConfigFactories()) {			//将加载了动态库的模块注册到协议工厂的成员变量中去;
		FATAL("Unable to configure factories");
		return false;
	}

	INFO("Configure acceptors");
	if (!gRs.pConfigFile->ConfigAcceptors()) {			//区分是UDP还是TCP,对所有要处理协议对应的端口进行socket绑定;并初始化每个协议事件响应函数;
		FATAL("Unable to configure acceptors");
		return false;
	}

	INFO("Configure instances");
	if (!gRs.pConfigFile->ConfigInstances()) {			//创建server的实例;
		FATAL("Unable to configure instances");
		return false;
	}

	INFO("Start I/O handlers manager: %s", NETWORK_REACTOR);
	IOHandlerManager::Start();								//;

	INFO("Configure applications");
	if (!gRs.pConfigFile->ConfigApplications()) {			//初始化各种应用;
		FATAL("Unable to configure applications");
		return false;
	}

	INFO("Install the quit signal");
	installQuitSignal(QuitSignalHandler);					//依据不同的平台, 如linux ,windows, android等安装不同的信号处理机;

	return true;
}


三,Run函数;

void Run() 
{
	if (!ApplyUIDGID()) 
	{
		FATAL("Unable to apply user id");
		exit(-1);
	}
	
	//打印显示流媒体服务器所有开启的应用,以及对应的端口;
	INFO("\n%s", STR(gRs.pConfigFile->GetServicesInfo()));
	
	//显示流媒体服务器的进程ID;
	INFO("GO! GO! GO! (%u)", (uint32_t) getpid());
	
	//调用网络等待事件发生;当对应端口的事件发生时,就调用事件处理函数进行处理;
	while (IOHandlerManager::Pulse()) 
	{							
		IOHandlerManager::DeleteDeadHandlers();
		ProtocolManager::CleanupDeadProtocols();
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值