摘要

  • SETUP 成功后,服务器才创建 RTSP 上下文并返回 Session 标识;SDP 描述和一条已建立的 TCP 连接都不能代替这次状态承诺。
  • 会话可先后使用不同控制连接,但 Session 标识不能替代正确 URI、方法状态、认证凭据或可用的媒体路径。
  • 服务器只有在状态仍存在且收到合格存活证据时才继续承认会话;TEARDOWN、超时或其他终止会让旧标识得到 454 Session Not Found。

遥控器的状态不在那根线里

1998 年的 RTSP 要解决一个看似矛盾的问题:命令像 HTTP 一样逐条到达,音视频却通常走另外的传输通道;与此同时,播放、暂停、定位和停止又必须作用于同一段持续状态。

RFC 2326 给出的答案很直接:不存在一种与整个操作等寿的“RTSP 连接”。服务器保存带标识的会话;在同一会话期间,客户端可以开启和关闭多条可靠传输连接。

这不是说 TCP 无关。命令和响应仍需经过它,媒体也可以与控制数据交织在同一连接上。真正被拆开的,是通道寿命和远端状态寿命。线断了,下一次按键暂时送不到;它本身并不等于 TEARDOWN,也不能证明服务器已经忘记所选媒体、端口和播放状态。

RTSP 因而给“命令从哪里来”和“命令作用于哪份记忆”安排了不同坐标。

描述一场演示,不等于为某人建立播放状态

客户端在 SETUP 之前可能先取得演示描述。RFC 4566 把 SDP 定义为媒体类型、编码、传输地址等信息的描述格式;它不是传输协议,也不会执行媒体控制。

SDP 和 RTSP 都使用“session”一词,容易制造一项错觉:只要描述中列出了音频、视频和控制引用,会话就已经存在。事实上,这份文档只说明有什么可用。它不能证明服务器为当前客户端保留了端口、接受了传输方案或分配了上下文。

SETUP 才跨过状态边界。客户端点名媒体资源并给出可接受的交付参数;服务器选中一种方案、保存参数并创建后续 PLAY、PAUSE 与 TEARDOWN 所要修改的状态。RFC 7826 在 2016 年用“RTSP session context”明确称呼这份服务器记录。

成功响应还在 Session 字段中交付由服务器生成的标识。SDP 回答“这套内容可以怎样控制”,SETUP 回答“这台服务器已经为此次交付接受了什么”。目录不能冒充预留结果。

第二个名称指向服务器记忆

媒体 URI 可以被许多观众共同使用。Session 标识则区分同一客户端对同一 URI 发起的多份交付状态,也能把音频、视频等资源纳入一个共同控制上下文。

RTSP 1.0 要求标识是不透明、随机且至少八个八位组长。RTSP 2.0 把范围定为 8 到 128 个字符,要求使用密码学随机生成方法,并建议约 128 比特熵。它引用 RFC 4086,关注的是随机源质量和猜中难度。

随机性没有把标识变成完整安全凭据。RFC 7826 紧接着警告:除非客户端、服务器和受信代理共同保密,Session 标识不能防止会话劫持。难猜不等于知道是谁,也不能证明订阅仍有效或当前策略允许这项操作。

RTSP 把认证交给 HTTP 认证框架等独立机制。比如 RFC 7616 的 Digest 有自己的质询、凭据、nonce 和重放控制。同一请求同时携带认证和 Session 并不重复:前者回答谁在某个保护空间内行动,后者回答要查找哪份已有状态。

找到会话,也要找对资源

客户端得到标识后,PLAY、PAUSE 和 TEARDOWN 等相关命令携带 Session。这样,新 TCP 连接可以继续操作旧上下文。但命令仍有 URI,方法仍受当前状态约束。

聚合控制最能说明这条边界。音频与视频可共享时间线,一次 PLAY 同时启动多路媒体;后续 SETUP 还可请求把另一资源加入现有上下文。即便如此,RFC 7826 仍要求聚合控制 URI 与单路媒体 URI 分开。代理要靠 URI 路由,服务器要靠它确认操作对象,日志也要靠它保存资源范围。

一个内部编号也许足以找到数据库记录,却不能定义对记录中所有对象都允许什么动作。因此,RTSP 分别规定了 Session 不存在、方法在当前状态无效、聚合操作层级错误等结果。查找键没有吞掉资源权力。

失败的扩展也不得损害旧状态。若把新资源加入会话的 SETUP 失败,RTSP 2.0 要求原有会话、传输和参数保持得像这次请求从未到达一样。协议不允许一次失败留下半套新配置。

一条连接可承载多场会话,一场会话也可更换连接

RTSP 2.0 要求服务器同时支持持久和临时 TCP 连接。客户端可以通过一条连接发送 SETUP 与 PLAY,关闭它,稍后再为 PAUSE 建立新连接。即使 NAT 状态到期导致 TCP 丢失,应用层上下文也可能继续存在。

反过来,一条持久连接也可以承载多场 RTSP 会话的命令,所以 socket 不能充当会话标识。为让服务器知道向客户端发起的请求应走哪条路,RTSP 2.0 规定同一时刻每场会话只能使用一条控制连接。它选择当前通道,却没有把通道寿命重新绑定到状态寿命。

媒体通路又是另一层。SETUP 可以协商 UDP 上的 RTP,也可把媒体与控制交织;跨越 NAT 和防火墙的实际可达性仍需验证。RFC 7825 为 RTSP 控制的媒体改造 ICE,正因为有效 Session 可以与不可用候选路径同时存在。Session 找到控制记录,ICE 与实际数据包证明网络路径。

服务器记忆需要存活证据

服务器不可能永久保留被遗弃的端口、缓存和状态。SETUP 响应可以宣布它愿意在命令或其他活动之间等待多久;未声明时默认 60 秒。RTSP 2.0 规定 timeout 只出现在响应中,而且已建立会话的时长不能中途改变。

任何引用该上下文的 RTSP 请求都可显示存活。单纯保活时,首选不带正文的 SET_PARAMETER。使用 RTP 时,RTCP 报告也可成为证据。RFC 3550 定义发送者和接收者报告;RFC 7826 再把网络地址、端口以及客户端所报告的服务器 RTP 源结合起来,判断客户端一侧仍在场。

这种证据是统计性的。RTCP 报告按计划发送,也会丢包。设计可以把误超时概率降得极低,却仍不能证明真人正在观看、某帧已经解码、PLAY 已持久生效或授权仍然成立。存活只支持“继续保留协议状态”这一项较窄结论。

客户端记住的字符,可能已经指向空处

正常结束通过 TEARDOWN。对聚合 URI 的操作可停止整个组并销毁上下文;状态允许时,媒体级 TEARDOWN 可移除一路资源,最后一路被移除时会话结束。超时、终止性重定向或不可恢复错误也可结束它。

这之后重复完全相同的标识不会复活服务器记录。454 Session Not Found 表示 Session 缺失、无效或已经超时。客户端可以准确保存旧值,服务器仍可合法回答它已经不再指向活动状态。

所以,会话从未“装在”标识里。标识只是指向一份可撤销记录。连接、URI、方法、认证、媒体路径与存活分别提供不同证据;任何一项都没有资格替其他项发言。