live555學習筆記15-RTCPInstance類小結
十五:RTCPInstance類小結
RTCPInstance是對rtcp通訊的封裝.RTCP主要是功能是統計包的收發為流量控制提供依據.RTCPInstance統計資料的取得僅依賴於RTPSink的一些函式(因為RTPSink傳送RTP包),所以RTCPInstance與其它類(GroupSock,RTPInterface等基礎類除外)基本關係不大,封裝的比較完整.
RTCPInstance靠RTPInterface提供網路通訊支援,所以它既支援rtcp over udp,又支援rtcp over tcp.
RTCPInstance接收到的包在函式static void incomingReportHandler(RTCPInstance* instance, int /*mask*/)中處理.
最值得關注的是這個成員函式:void setSpecificRRHandler(netAddressBits fromAddress, Port fromPort,TaskFunc* handlerTask, void* clientData).它的作用是讓呼叫者可以設定回撥函式,呼叫者就可以在收到RR包時做出一定的動作.引數fromAddress和fromPort指明要對哪個客戶端的RR包做出響應.
利用這個機制的例子是RTSPServer::RTSPClientSession.它會把自己的RRHandler函式經過層層傳遞,最終傳給RTCPInstance.於是RTSPServer::RTSPClientSession就可以在每次收到對應的客戶端的RR包時呼叫它傳入的函式,這個函式是void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPClientSession* clientSession).此函式只是以下函式的過渡:
void RTSPServer::RTSPClientSession::noteLiveness() { #ifdef DEBUG fprintf(stderr, "Liveness indication from client at %s\n", our_inet_ntoa(fClientAddr.sin_addr)); #endif if (fOurServer.fReclamationTestSeconds > 0) { envir().taskScheduler().rescheduleDelayedTask(fLivenessCheckTask, fOurServer.fReclamationTestSeconds * 1000000, (TaskFunc*) livenessTimeoutTask, this); } }
可以看到,每收到一次指定客戶端的RR包,就重置一下livenessTimeoutTask()的執行時間,如果livenessTimeoutTask()一旦執行,看一下livenessTimeoutTask():
void RTSPServer::RTSPClientSession::livenessTimeoutTask(RTSPClientSession* clientSession) { // If this gets called, the client session is assumed to have timed out, // so delete it: #ifdef DEBUG fprintf(stderr, "RTSP client session from %s has timed out (due to inactivity)\n", our_inet_ntoa(clientSession->fClientAddr.sin_addr)); #endif delete clientSession; }
那麼RTSPServer::RTSPClientSession就會自殺(真是想不開啊).也就是說fOurServer.fReclamationTestSeconds * 1000000是超時時間(預設好像是60秒).
如果你想監視一個客戶端,最好的方式就是向RTCPInstance註冊RRHandle.