对RTSP Session进行管理的代码在Server.tproj/RTSPSession.cpp中。RTSPSession对象在构造函数中,首先将状态初始化为kReadingFirstRequest。
RTSPSession::RTSPSession( Bool16 doReportHTTPConnectionAddress )
: RTSPSessionInterface(),
fRequest(NULL),
fRTPSession(NULL),
fReadMutex(),
fHTTPMethod( kHTTPMethodInit ),
fWasHTTPRequest( false ),
fFoundValidAccept( false),
fDoReportHTTPConnectionAddress(doReportHTTPConnectionAddress),
fCurrentModule(0),
fState(kReadingFirstRequest)
{
......
}
RTSPSession::Run()实现了一个状态机,可以看其代码结构:
SInt64 RTSPSession::Run()
{
……
while (this->IsLiveSession())
{
switch (fState)
{
case kReadingFirstRequest:
{
……
if (err == QTSS_RequestArrived)
fState = kHTTPFilteringRequest;
if (err == E2BIG)
fState = kHaveNonTunnelMessage;
}
continue;
case kHTTPFilteringRequest:
{
fState = kHaveNonTunnelMessage; // assume it's not a tunnel setup message
// prefilter will set correct tunnel state if it is.
PreFilterForHTTPProxyTunnel();
……
}
case kReadingRequest:
{
……
fState = kHaveNonTunnelMessage;
}
case kHaveNonTunnelMessage:
{
……
fState = kFilteringRequest;
}
case kFilteringRequest:
{
……
if (fRequest->HasResponseBeenSent())
{
fState = kPostProcessingRequest;
break;
}
fState = kRoutingRequest;
}
case kRoutingRequest:
{
……
if(fRequest->SkipAuthorization())
{
fState = kPreprocessingRequest;
……
}
else
fState = kAuthenticatingRequest;
}
case kAuthenticatingRequest:
{
……
if (fRequest->HasResponseBeenSent())
{
fState = kPostProcessingRequest;
break;
}
fState = kAuthorizingRequest;
}
case kAuthorizingRequest:
{
if (fRequest->HasResponseBeenSent())
{
fState = kPostProcessingRequest;
break;
}
fState = kPreprocessingRequest;
}
case kPreprocessingRequest:
{
……
if (fRequest->HasResponseBeenSent())
{
fState = kPostProcessingRequest;
break;
}
fState = kProcessingRequest;
}
case kProcessingRequest:
{
……
fState = kPostProcessingRequest;
}
case kPostProcessingRequest:
{
……
fState = kSendingResponse;
}
case kSendingResponse:
{
……
fState = kCleaningUp;
}
case kCleaningUp:
{
……
fState = kReadingRequest;
}
}
}
……
}
对于第一次RTSP请求,在kReadingFirstRequest中,如果收到完整的RTSP请求,会转入kHTTPFilteringRequest。在kHTTPFilteringRequest状态,会通过PreFilterForHTTPProxyTunnel()检查这个RTSP请求是否通过HTTP Tunnel。如果是普通的RTSP请求,则进入kHaveNonTunnelMessage状态;如果是走HTTP POST,则进入kSocketHasBeenBoundIntoHTTPTunnel状态;如果是走HTTP GET,则进入kReadingRequest状态。
对于后续的RTSP请求,则直接进入kReadingRequest状态。(第一次RTSP请求结束后,状态被置为kReadingRequest。)
在kReadingRequest状态,确保收到完整的RTSP请求数据后,进入kHaveNonTunnelMessage状态。
在kHaveNonTunnelMessage状态,生成RTSPRequest对象,检查RTSP请求数据的正确性,进入kFilteringRequest状态。
在kFilteringRequest状态,会调用所有注册了QTSS_RTSPFilter_Role角色的模块,随后进入kRoutingRequest状态。
在kRoutingRequest状态,会调用所有注册了QTSS_RTSPRoute_Role角色的模块,然后判断是否需要进行认证,分别进入kAuthenticatingRequest和kPreprocessingRequest状态。
kAuthenticatingRequest状态要解决的问题是:用户是不是这个系统的合法用户。若是合法用户,则进入kAuthorizingRequest状态,这里会解决另一个问题:用户对要访问的资源是否真的有权限。
对RTSP请求的真正处理放在kProcessingRequest阶段,而其前后则有预处理kPreprocessingRequest阶段和后处理kProcessingRequest阶段。然后进入kSendingResponse阶段发回数据,再进入kCleaningUp阶段做清理工作,最后把状态设为kReadingRequest准备处理下一个RTSP请求。
认证通过以后,RTSP请求的状态会在kReadingRequest->kHaveNonTunnelMessage->kFilteringRequest->kRoutingRequest->kPreprocessingRequest->kProcessingRequest->kPostProcessingRequest->kSendingResponse->kCleaningUp->kReadingRequest