服务器媒体事件和信号处理
Posted qianbo_insist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了服务器媒体事件和信号处理相关的知识,希望对你有一定的参考价值。
事件类型
总体来说,划分事件是为了在脚本中注册各类事件,从而向其他模块,可执行文件,通知各种异常和非异常的发生点,比如一个客户端链接上来,就是一个非异常发生点,超时脱线就是一个异常发生点。
架构上划分事件清楚,就可以更加方便地将流程整理清楚。事件可以分为
1 服务事件
2 会话session事件
3 服务状态事件,比如录像开始
switch(_type)
// StreamEventType
case EventType::ServerStarted:
case EventType::HostCreated:
case EventType::HostDeleted:
case EventType::AppCreated:
case EventType::AppDeleted:
case EventType::StreamCreated:
case EventType::StreamDeleted:
case EventType::StreamOriginLinkUpdated:
case EventType::StreamOutputsUpdated:
_category = EventCategory::StreamEventType;
break;
// SessionEventType
case EventType::SessionConnected:
case EventType::SessionDisconnected:
_category = EventCategory::SessionEventType;
break;
// ActoinEventType
case EventType::ApiCalled:
case EventType::RecordingStarted:
case EventType::RecordingStopped:
case EventType::PushStarted:
case EventType::PushStopped:
_category = EventCategory::ActoinEventType;
break;
// NotificationEventType
case EventType::Info:
case EventType::Error:
_category = EventCategory::NotificationEventType;
break;
// StatisticsEventType
case EventType::ServerStat:
_category = EventCategory::StatisticsEventType;
break;
事件翻译
将事件翻译成可以认识的字符串
String Event::GetTypeString() const
switch(_type)
// StreamEventType
case EventType::ServerStarted:
return "ServerStarted";
case EventType::HostCreated:
return "HostCreated";
case EventType::HostDeleted:
return "HostDeleted";
case EventType::AppCreated:
return "AppCreated";
case EventType::AppDeleted:
return "AppDeleted";
case EventType::StreamCreated:
return "StreamCreated";
case EventType::StreamDeleted:
return "StreamDeleted";
case EventType::StreamOriginLinkUpdated:
return "StreamOriginLinkUpdated";
case EventType::StreamOutputsUpdated:
return "StreamOutputsUpdated";
// SessionEventType
case EventType::SessionConnected:
return "SessionConnected";
case EventType::SessionDisconnected:
return "SessionDisconnected";
// ActoinEventType
case EventType::ApiCalled:
return "ApiCalled";
case EventType::RecordingStarted:
return "RecordingStarted";
case EventType::RecordingStopped:
return "RecordingStopped";
case EventType::PushStarted:
return "PushStarted";
case EventType::PushStopped:
return "PushStopped";
// NotificationEventType
case EventType::Info:
return "Info";
case EventType::Error:
return "Error";
// StatisticsEventType
case EventType::ServerStat:
return "ServerStat";
return "";
事件翻译成json
为了通信解释,可以将事件翻译成json,如下代码所示
String Event::SerializeToJson() const
Json::Value json_root;
// Fill common values
json_root["eventVersion"] = EVENT_VERSION;
json_root["timestampMillis"] = _creation_time_msec;
json_root["userKey"] = _server_metric->GetConfig()->GetAnalytics().GetUserKey().CStr();
json_root["serverID"] = _server_metric->GetConfig()->GetID().CStr();
// Fill root["event"]
Json::Value &json_event = json_root["event"];
json_event["type"] = GetTypeString().CStr();
if(_message.IsEmpty() == false)
json_event["message"] = _message.CStr();
Json::Value &json_producer = json_event["producer"];
FillProducer(json_producer);
// Fill root["data"]
Json::Value &json_data = json_root["data"];
if(_category == EventCategory::StreamEventType)
//TODO(Getroot): Implement this
json_data["dataType"] = "Not Implemented";
Json::Value &json_server_info = json_data["serverInfo"];
FillServerInfo(json_server_info);
else if(_category == EventCategory::StatisticsEventType)
Json::Value &json_server_stat = json_data["serverStat"];
FillServerStatistics(json_server_stat);
Json::StreamWriterBuilder builder;
/*
Default StreamWriterBuilder settings
(*settings)["commentStyle"] = "All";
(*settings)["indentation"] = "\\t";
(*settings)["enableYAMLCompatibility"] = false;
(*settings)["dropNullPlaceholders"] = false;
(*settings)["useSpecialFloats"] = false;
(*settings)["emitUTF8"] = false;
(*settings)["precision"] = 17;
(*settings)["precisionType"] = "significant";
*/
logtd("%s", json_root.toStyledString().c_str());
builder["indentation"] = "";
return Json::writeString(builder, json_root).c_str();
信号处理
信号是一种软件中断,提供了异步事件的处理机制,比如SIGCHLD,代表子进程终止信号,子进程终止后捕获该信号,处理子进程异常信息。
SIGUSR1 SIGUSR2 两个都是进程自定义信号,这些信号是给用户自定义用的,内核从来不发送他们,进程可以使用任何目的使用这两个信号。
接下来就是更多的信号处理,如下所示,信号就很多了
bool InitializeSignals()
// 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
// 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
// 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
// 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
// 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
// 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
// 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
// 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
// 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
// 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
// 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
// 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
// 63) SIGRTMAX-1 64) SIGRTMAX
return InitializeAbortSignal() &&
InitializeUser1Signal() &&
InitializeReloadSignal() &&
InitializeTerminateSignal();
信号处理程序举例
#include <stdio.h>
static void sigint_handle(int signo)
printf("............................");
exit(EXIT_SUCCESS);
int main(void)
if(signal(SIGINT, sigint_handle) == SIG_ERR)
fprintf(stderr,"can not handle\\n";
exit(EXIT_FAILURE);
for(;;)
pause();
return 0;
其中SIGINT是处理用户输入中断符号事件,比如调试使用ctrl+c,而pause是系统调用函数,将挂起程序,知道有信号,信号由内核发送给进程,从而唤醒系统进程。这个需要读者掌握多一些操作系统的原理了。
事件和信号结合
除了可以写脚本来处理,比如lua,或者javascript等,还可以将事件和信号联系起来,进程系统级别的调用,比如碰到SIGSEGV 内存处理异常,SIGXCPU 进程资源超限制等信号,我们收到这些信号后可以重启或关闭程序。
以上是关于服务器媒体事件和信号处理的主要内容,如果未能解决你的问题,请参考以下文章