1. Introduction (简介)
1. Introduction (简介)
本文档描述了如何使用 W3C Web Real-Time Communication (WebRTC) RTCPeerConnection 接口 [W3C.webrtc] 来控制多媒体会话的建立, 管理和拆除。
1.1 General Design of JSEP (JSEP的总体设计)
WebRTC 呼叫建立被设计为专注于控制媒体平面, 尽可能将信令平面行为留给应用程序。其理由是不同的应用程序可能更倾向于使用不同的协议, 例如现有的 SIP 呼叫信令协议, 或针对特定应用程序定制的协议, 可能用于新颖的用例。在这种方法中, 需要交换的关键信息是多媒体会话描述, 它指定了建立媒体平面所需的传输和媒体配置信息。
考虑到这些因素, 本文档描述了 JavaScript Session Establishment Protocol (JSEP), 它允许从 JavaScript 完全控制信令状态机。如上所述, JSEP 假设一个模型, 其中 JavaScript 应用程序在包含 WebRTC API 的运行时内执行 ("JSEP implementation")。JSEP 实现几乎完全与核心信令流分离, 后者由 JavaScript 使用两个接口处理: (1) 传入本地和远程会话描述, (2) 与 Interactive Connectivity Establishment (ICE) 状态机 [RFC8445] 交互。JSEP 实现和 JavaScript 应用程序的组合在本文档中被称为 "JSEP endpoint"。
在本文档中, JSEP 的使用被描述为总是发生在两个 JSEP 端点之间。但请注意, 在许多情况下, 它实际上是在 JSEP 端点和某种服务器之间, 例如网关或 Multipoint Control Unit (MCU)。这种区别对 JSEP 端点是不可见的; 它只是遵循通过 API 给出的指令。
JSEP 对会话描述的处理简单直接。每当需要 offer/answer 交换时, 发起方通过调用 createOffer API 创建一个 offer。然后应用程序使用该 offer 通过 setLocalDescription API 设置其本地配置。最后, offer 通过其首选的信令机制 (例如 WebSockets) 发送到远程端; 收到该 offer 后, 远程方使用 setRemoteDescription API 安装它。
为了完成 offer/answer 交换, 远程方使用 createAnswer API 生成适当的 answer, 使用 setLocalDescription API 应用它, 并通过信令通道将 answer 发送回发起者。当发起者收到该 answer 时, 它使用 setRemoteDescription API 安装它, 初始设置就完成了。此过程可以重复进行额外的 offer/answer 交换。
关于 ICE [RFC8445], JSEP 将 ICE 状态机与整体信令状态机解耦。ICE 状态机必须保留在 JSEP 实现中, 因为只有实现才具有候选者和其他传输信息的必要知识。执行这种分离为将会话描述与传输解耦的协议提供了额外的灵活性。例如, 在传统的 SIP 中, 每个 offer 或 answer 都是自包含的, 包括会话描述和传输信息。然而, [RFC8840] 允许 SIP 与 Trickle ICE [RFC8838] 一起使用, 其中会话描述可以立即发送, 传输信息可以在可用时发送。单独发送传输信息可以允许更快的 ICE 和 DTLS 启动, 因为 ICE 检查可以在任何传输信息可用时立即开始, 而不是等待所有信息。JSEP 将 ICE 和信令状态机解耦使其能够适应任一模型。
虽然它抽象了信令, 但 JSEP 方法要求应用程序了解信令过程。虽然应用程序不需要理解会话描述的内容来建立呼叫, 但应用程序必须在正确的时间调用正确的 API, 将会话描述和 ICE 信息转换为其所选信令协议的定义消息, 并对从另一端接收的消息执行反向转换。
使应用程序生活更轻松的一种方法是提供一个 JavaScript 库, 向开发人员隐藏这种复杂性; 该库将实现给定的信令协议及其状态机和序列化代码, 向应用程序开发人员呈现更高级的面向呼叫的接口。例如, 存在在 JSEP API 之上提供 SIP [RFC3261] 和 Extensible Messaging and Presence Protocol (XMPP) [RFC6120] 信令协议实现的库。因此, JSEP 为经验丰富的开发人员提供了更大的控制权, 而不会给新手开发人员带来任何额外的复杂性。
1.2 Other Approaches Considered (考虑的其他方法)
考虑的一种替代 JSEP 的方法是包含一个轻量级信令协议。API 不提供会话描述, 而是产生和消费来自该协议的消息。虽然提供了更高级的 API, 但这将更多的信令控制权放在了 JSEP 实现中, 迫使它必须理解和处理诸如信令冲突 (参见 [RFC3264], 第 4 节) 之类的概念。
考虑但未选择的第二种方法是将媒体控制对象的管理与会话描述解耦, 而是提供直接控制每个组件的 API。这被拒绝是基于以下论点: 要求向应用程序程序员暴露这种级别的复杂性是无益的; 它会 (1) 导致即使是一个简单的示例也需要大量代码来编排所有需要的交互的 API, (2) 创建一个需要商定和记录的大型 API 表面。此外, 这些 API 点可以按任何顺序调用, 导致与媒体子系统的交互比 JSEP 方法更复杂, 后者指定了如何评估和应用会话描述。
考虑的 JSEP 的一个变体是保持基本的面向会话描述的 API, 但将生成 offer 和 answer 的机制移出 JSEP 实现。这种方法不是在实现中提供 createOffer/createAnswer 方法, 而是暴露一个 getCapabilities API, 它将为应用程序提供生成自己的会话描述所需的信息。这增加了应用程序需要做的工作量; 它需要知道如何从能力生成会话描述, 特别是如何从任意 offer 和支持的能力生成正确的 answer。虽然这当然可以通过使用上面提到的库来解决, 但它基本上强制即使对于简单的示例也要使用该库。提供 createOffer/createAnswer 避免了这个问题。
1.3 Contradiction regarding bundle-only "m=" sections (关于bundle-only "m="部分的矛盾)
自 WebRTC 规范文档批准以来, IETF 已经意识到指定 JSEP 的文档和指定 BUNDLE 的文档 (本 RFC 和 [RFC8843], 分别) 之间存在不一致。与其进一步延迟发布以达成解决方案, 不如按原始批准的方式发布文档。IETF 打算重新开始这些技术的工作, 并且一旦有解决方案, 将尽快发布这些文档的修订版本。
具体问题涉及对被指定为 bundle-only 的 "m=" 部分的处理, 如本 RFC 的第 4.1.1 节所述。目前, JSEP 和 BUNDLE 之间, 以及这些规范与现有浏览器实现之间存在分歧:
-
JSEP 规定这些 "m=" 部分应该在初始 offer 中使用端口零并添加 "a=bundle-only" 属性, 但不应该在 answer 或后续 offer 中。
-
BUNDLE 规定这些 "m=" 部分应该按照前一点所述进行标记, 但在所有 offer 和 answer 中。
-
大多数当前浏览器不会用端口零标记任何 "m=" 部分, 而是对所有捆绑的 "m=" 部分使用相同的端口; 其他一些浏览器遵循 JSEP 行为。