本篇文章简要介绍服务器部分与RTSP协议实现相关的业务代码实现。
在介绍服务器有关RTSP业务代码实现之前,我们首先要明确服务器与客户端建立RTSP通信的基本过程,如下所述:
·C --> S:Send OPTIONS Cmd,S --> C:Handle OPTIONS Cmd and Send Response;
·C --> S:Send DESCRIBE Cmd,S --> C:Handle DESCRIBE Cmd and Send Response;
·C --> S:Send SETUP Cmd,S --> C:Handle SETUP Cmd and Send Response;
·C --> S:Send PLAY Cmd,S --> C:Handle PLAY Cmd and Send Response;
·C --> S:Send PAUSE Cmd,S --> C:Handle PAUSE Cmd and Send Response;
·C --> S:Send TEARDOWN Cmd,S --> C:Handle TEARDOWN Cmd and Send Response。
正如前一篇文章中所提到的那样,在代码上实现RTSP协议的简单应用还是相对简单的。在参考了live555开源项目中关于RTSP协议的实现代码之后,针对本项目,笔者将只对其中的几个重要会话状态OPTIONS、DESCRIBE、SETUP、PLAY、PAUSE、TEARDOWN作初步的代码实现,同时在本项目中将不考虑用户验证的问题。以下是关于上述会话状态和若干状态码的主要方法:
该方法用来处理接收到的客户端请求,首先解析了请求字符串,输出会话命令、请求的URL、流名称、序号等内容(out string cmdName, out string rtspUrl, out string urlPreSuffix, out string urlSuffix, out string cseq);然后根据会话命令通过switch...case语句来分类处理;最后将生成的响应字符串发送给指定的客户端。
以下是方法HandleOptionsCmd、HandleBadCmd、HandleNotSupportCmd、HandleNotFoundCmd、HandleUnsupportedTransportCmd的代码实现部分:
值得注意的是,这里并没有列出方法HandleDescribeCmd、HandleSetupCmd、HandlePlayCmd、HandlePauseCmd和HandleTearDownCmd的代码实现,主要原因是其中牵扯到媒体源的选择(当然,笔者已初步决定了使用TS流格式的文件作为媒体源)及RTP/RTCP等的建立过程,而笔者对其中的一些过程尚存在一些不明晰之处,因而思路仍在不断调整之中。
不过,对于处理DESCRIBE指令,其首先要根据流名称查找对应的ServerMediaSession,然后生成SDP描述信息,接着将SDP描述信息等组装成响应字符串并最后发回给客户端。
而对于处理SETUP指令,首先是要确认ServerMediaSession的存在,然后解析传输头信息(ParseTransportHeader),然后要拿到相关的Parameters,最后组装成响应信息并发回给客户端。关于这一块目前的主要问题是在对GetStreamParameters的处理尚有一些不明确之处。
对于处理PLAY、PAUSE、TEARDOWN,当前的思路主要是通过ServerMediaSubsession调用相应的StartStream、PauseStream和DeleteStream(是否需要这么做,还有待进一步考虑)方法。
另外,为支持TCP和UDP传输,特别编写了一个ClientSocketBase作为ClientSocketTcp和ClientSocketUdp的基类,该类包含一些事件和虚方法,代码如下所示:
当前关于TCP和UDP的数据接收和发送,均采用异步模式,但是其中又有一些例外,这将在下一篇文章中讲述,敬请关注。