精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
QuickTime流媒体服务器通过调用模块的特定角色,来处理客户端的请求。每个角色都用来处理一个特定任务。这个部分的内容将描述在服务器启动和关闭,以及处理客户请求的时候,是如何和模块协同工作的。
这部分的主要内容如下:
服务器的启动和关闭
RTSP请求的处理
图 1-3显示的是服务器在启动和关闭的时候如何和Register(登记),Initialize(初始化),和Shutdown(关闭)这些角色协同工作的。
服务器在启动的时候,会首先装载没有被编译到服务器里面的模块(即动态模块),然后再装载编译为服务器一部分的模块(即静态模块)。如果您正在书写模块来代替现有的服务器功能,则请将它编译为动态模块,使它率先被服务器装载。
在模块装载完成之后,服务器会调用每个QTSS模块的Register(注册)角色,每个模块都必须支持这个角色。在Register角色中,模块会调用QTSS_AddRole函数来指定自己支持的其它角色。
接下来服务器就以Initialize(初始化)角色调用每一个注册支持该角色的模块。Initialize角色执行模块所需要的任何初始化任务,比如分配内存和初始化全局的数据结构。
在服务器关闭的时候,服务器以Shutdown角色调用每个注册了该角色模块。在处理Shutdown角色的时候,模块应该执行一些收拾现场的任务,并释放全局的数据结构。
在服务器调用所有注册了Initialize角色的模块之后,就已经为接收来自客户端的请求做好准备了。这些请求就是RTSP请求。图 1-4显示的是一个RTSP请求的实例:
当服务器收到一个RTSP请求时,就会创建一个RTSP请求对象,该对象是一些描述请求的属性的集合。在当前这个时间点上,qtssRTSPReqFullRequest属性是唯一有值的属性,其值组成了RTSP请求的完整内容。
接着服务器会根据预先定义好的顺序,调用各个模块的相关角色。这个调用系列如图 1-5所示。
请注意:服务器调用特定模块角色的顺序是不确定的。
在处理RTSP请求的时候,服务器调用的第一个角色是RTSP Filter(过滤器)角色。它会调用所有注册了RTSP Filter角色的模块,并将RTSP请求对象作为参数传递给它。每个RTSP Filter角色都可以改变qtssRTSPReqFullRequest属性的值。比如说,一个RTSP Filter角色可以把/foo/foo.mov改为/bar/bar.mov,从而改变用于满足请求的文件夹。
重要提示
任何处理RTSP Filter角色的模块对客户端进行响应,都会导致服务器跳过其它已经注册了RTSP Filter角色的模块,以及跳过已经注册其它RTSP角色的模块,然后立即调用该响应模块的RTSP Postprocessor(后处理)角色。这里所说的对客户进行响应是指模块向客户端发送任何形式的数据。
在调用了所有RTSP Filter(过滤器)角色之后,服务器就会对请求进行解析。解析请求包括填充RTSP对象剩余的属性值,以及创建下面两个会话:
RTSP请求解析完成之后,服务器会以RTSP Route(路由)角色调用所有注册了该角色的模块,并传入一个RTSP对象。每个RTSP Route角色都可以使用RTSP对象中的属性值来确定是否要改变qtssRTSPReqRootDir属性的值,进而改变用于处理当前请求的目录。举例来说,如果语言的类型是French(法语),则模块可以把qtssRTSPReqRootDir属性修改到包含法语版本的被请求文件的目录下。
重要提示
任何处理RTSP Route角色的模块对客户端进行响应,会导致服务器跳过其它注册了RTSP Route角色的模块,以及跳过注册了其它RTSP角色的模块,并且立即调用响应模块的RTSP Postprocessor(后处理)角色。
在调用了所有RTSP Route角色之后,服务器就会以RTSP Preprocessor角色调用每个注册了该角色的模块。通常情况下,RTSP Preprocessor角色会通过qtssRTSPReqAbsoluteURL属性值来确定当前请求是否和模块处理的请求的类型相匹配。
如果请求的类型互相匹配,则RTSP Preprocessor角色就调用QTSS_Write或者QTSS_WriteV函数来向客户发送数据,对客户端进行响应。如果只需要发送标准响应,则模块可以调用QTSS_SendStandardRTSPResponse,或者QTSS_AppendRTSPHeader和QTSS_SendRTSPHeaders函数。
重要提示
任何处理RTSP Preprocessor角色的模块对客户端进行响应,都会导致服务器跳过注册了RTSP Preprocessor角色的所有其它模块,以及跳过注册了其它RTSP角色的所有模块,并且立即调用响应模块的RTSP Postprocessor角色。
如果没有RTSP Preprocessor角色对RTSP的请求进行响应,则服务器就以RTSP Request(请求)角色调用成功注册了该角色的模块(第一个注册RTSP Request角色的模块,是唯一一个可以注册RTSP Request角色的模块)。RTSP Request角色负责响应所有没有被RTSP Preprocessor角色(的模块)处理过的RTSP请求。
RTSP Request角色对请求进行处理之后,服务器就调用注册了RTSP Postprocessor角色的模块。RTSP Postprocessor角色通常执行一些统计任务,比如记录各种统计信息。
处理RTSP Preprocessor或者RTSP Request角色的模块可能需要为特定的客户会话生成一些媒体数据。如果这样的话,模块可以通过调用QTSS_Play函数来实现,这个函数会使模块的RTP Send Packets(RTP发送数据包)角色被调用,如图 1-6所示:
RTP Send Packets角色调用QTSS_Write或者QTSS_WriteV函数,在RTP会话的基础上向客户发送数据。当RTP Send Packets角色发送完成一些数据包之后,就会把控制权返回给服务器,并指定服务器下次调用模块的RTP Send Packets角色的间隔时间。这个周期会一直重复,直到所有的媒体数据包被发送完成,或者由于客户请求的原因需要暂停或中止客户会话为止。