live555ProxyServer.cpp分析:初始化流程


1、创建RTSPServer对象,主要是初始化父类GenericMediaServer,创建服务端socket
    先调用setUpOurSocket函数建立TCP连接,获得RTSP连接socket
    初始化父类GenericMediaServer,父类中存储了fServerMediaSessions,fClientConnections,fClientSessions三个map, fServerMediaSessions支持提供的Media服务,比如客户端通过rtsp://<ip>/rtsp1访问时,会通过 fServerMediaSessions来查找对应的ServerMediaSession, ServerMediaSession 在框架中起到承上启下的作用,比如说rtsp客户端发送DESCRIBE命令时,通过 ServerMediaSession的generateSDPDescription接口 找到对应subsession下的sdp信息,在SETUP命令时建立底层rtp发送所需要的source和sink
        fClientConnections表示客户端的连接,RTSPServer在接收到连接上来的客户端请求时,通过fClientConnections设置的回调接口来解析处理相应的命令
        fClientSessions主要用在已经建立好RTSP信令的客户端,当传输RTP包时,基本是通过fClientSessions的

2、创建ProxyServerMediaSession,主要通过defaultCreateNewProxyRTSPClientFunc创建出了ProxyRTSPClient,同时初始化RTSPClient,RTSPClient主要负责 作为服务器,初始化客户端,通过 defaultCreateNewProxyRTSPClientFunc接口。创建ProxyRTSPClient和父类RTSPClient,RTSPClient封装了RTSP接口,负责 发送RTSP数据给客户端,但是没有处理功能, ProxyRTSPClient完成了RTSP发送给客户端后的回调功能,注意,此时socket并没有建立,即并没有去连接服务端
    
    再次调用ProxyRTSPClient::sendDESCRIBE(fProxyRTSPClient),向客户端发送"DESCRIBE"命令,同时设置返回时的回调continueAfterDESCRIBE,这个时候在 RTSPClient::sendDescribeCommand-》sendRequest中调用了openConnection()函数,在setupStreamSocket()函数中创建出了socket,后面和客户端通信 就使用这个,创建出socket通道后,设置了这个socket的handler为incomingDataHandler,并在后面会加入RTSPServer的select中,当这个socket可读时, 会调用 incomingDataHandler这个接口函数,最终会执行RTSPClient::incomingDataHandler1(),其中调用readSocket读取信息,并调用handleResponseBytes() 函数解析客户端发送过来的信息,因为发送的是DESCRIBE命令,所以会调用continueAfterDESCRIBE回调函数,根据客户端发送过来的sdp信息,调用
fOurServerMediaSession.continueAfterDESCRIBE()函数

    continueAfterDESCRIBE主要工作是通过sdp建立fClientMediaSession,fClientMediaSession从sdp信息中,解析出对应的媒体信息,并生成相对应的subsession,
    通过调用initializeWithSDP()函数解析sdp(Session Description Protocol)信息,贴一个sdp的信息:
            
    不难发现,有两条Media描述,一个是音频,一个是视频,并且Media的传输协议,访问地址、格式等等信息也都发过来了,因此,我们需要对Audio和Video分别 再建立ServerSubSession来对应他们, initializeWithSDP函数正是干这个事情的,并且把对应SDP信息中对Media的描述信息也保存到SubSession,等待真正 的播放请求过来时,再执行创建sock通道的工作。

     不难发现,ProxyServerMediaSession初始化的主要工作就是作为客户端先得到ipcamera或者说是转发原服务地址的sdp信息,建立储备信息,等待播放器或者说客户端
    建立连接

3、把ProxyServerMediaSession添加到RTSPServer中,这样当RTSP客户端连接上时,通过地址作为key值就能找到ProxyServerMediaSession进行处理,然后等待客户端的连接

4、执行env->taskScheduler().doEventLoop(),会循环调用BasicTaskScheduler::SingleStep()对加入关心的socket异步跟踪它们的读写执行情况,RTSPServer在初始化的时候 已经通过父类GenericMediaServer构造函数中的turnOnBackgroundReadHandling,对RTSPServer的socket进行了可读的跟踪。 turnOnBackgroundReadHandling最终 会调用BasicTaskScheduler::setBackgroundHandling,把RTSPServer的socket放到BasicTaskScheduler对象的fHandlers的map中,并且设置处理函数为incomingConnectionHandler, 当新的客户端连接上来的时候,select会检测到,遍历fHandlers的map中的socket对应的处理函数来执行,就开始执行incomingConnectionHandler函数了。
    最终执行了GenericMediaServer::incomingConnectionHandlerOnSocket函数中的accept建立新连接客户端的sock通道,那么根据之前的描述,应该能想得到肯定要为这个客户端建立新的clientsession,
因此调用到RTSPServer::createNewClientSession,并创建了RTSPClientSession,继承自GenericMediaServer::ClientConnection,因此会调用GenericMediaServer::ClientConnection的构造函数,
通过fOurServer.fClientConnections->Add加入到fClientConnections中,并且调用了setBackgroundHandling,也把socket加入到了handler中,并设置了incomingRequestHandler回调接口,当客户端发送数据过来的时候,会执行这个函数。
    通过上面的分析,我们也知道了live555是通过Task来增加处理任务,然后通过select执行回调的单线程方式处理网络事务的,当客户端通过rtsp://请求时,最终执行到了incomingRequestHandler函数,最终执行GenericMediaServer::ClientConnection::incomingRequestHandler,读取数据,并开始通过handleRequestBytes解析读取到的数据内容,即客户端请求最终的数据处理接口是handleRequestBytes函数,RTSP等协议的处理也能够通过这个接口中找到,实际对应的处理函数为RTSPServer::RTSPClientConnection::handleRequestBytes。

你可能感兴趣的:(media,代理,proxy,多媒体,Live555)