6.2 RTCDataChannel

RTCDataChannel接口表示两个对等体之间的双向数据信道。 RTCDataChannel是通过RTCPeerConnection对象上的工厂方法创建的。浏览器之间发送的消息在[RTCWEB-DATA]和[RTCWEB-DATA-PROTOCOL]中描述。

有两种方法可以与RTCDataChannel建立连接。第一种方法是在其中一个对等体上创建一个RTCDataChannel,并且协商的RTCDataChannelInit字典成员为未设置或被设置为默认值false。这将在带内公布新通道,并在另一个对等体上触发带有相应RTCDataChannel对象的RTCDataChannelEvent。第二种方法是让应用程序协商RTCDataChannel。为此,创建一个RTCDataChannel对象,将协商的RTCDataChannelInit字典成员设置为true,并通过带外信号(例如通过Web服务器)向另一方发出信号,它应该创建一个带有协商的RTCDataChannelInit字典成员集的相应RTCDataChannel,字典成员被设置为true,并且具有相同id。这将连接两个单独创建的RTCDataChannel对象。第二种方法可以创建具有非对称属性的通道,并通过指定匹配的ID以声明方式创建通道。

每个RTCDataChannel都有一个关联的底层数据传输,用于将实际数据传输到另一个对等端。在SCTP数据信道利用RTCSctpTransport(表示SCTP关联的状态)的情况下,底层数据传输是SCTP流对。底层数据传输的传输属性(例如有序发送设置和可靠性模式)由对等方在创建通道时配置。创建通道后,通道的属性不会更改。对等体之间的实际有线协议由WebRTC DataChannel协议规范[RTCWEB-DATA]指定。

可以将RTCDataChannel配置为在不同的依赖模式下操作。可靠的信道确保通过重新传输在另一个对等体上传达数据。不可靠信道被配置为限制重传次数(maxRetransmits)或设置允许传输(包括重传)的时间(maxPacketLifeTime)。这些属性不能同时使用,这样做会导致错误。不设置任何这些属性会得到可靠的通道。

使用createDataChannel创建或通过RTCDataChannelEvent调度的RTCDataChannel必须最初处于connecing状态。当RTCDataChannel对象的底层数据传输准备就绪时,用户代理必须宣布RTCDataChannel为open。

要创建RTCDataChannel,请运行以下步骤:

  1. 让channel成为新创建的RTCDataChannel对象。
  2. 让通道将[[ReadyState]]内部插槽初始化为“connecting”测试1
  3. 让通道将[[BufferedAmount]]内部插槽初始化为0
  4. 让通道具有内部插槽,名为[[DataChannelLabel]],[[Ordered]],[[MaxPacketLifeTime]],[[MaxRetransmits]],[[DataChannelProtocol]],[[Negotiated]],[[DataChannelId]]和[ [DataChannelPriority]。
  5. 返回通道。

当用户代理宣布RTCDataChannel为open时,用户代理必须对任务进行排队,运行以下步骤:

  1. 如果关联的RTCPeerConnection对象的[[IsClosed]]插槽为true,则中止这些步骤。
  2. 让channel成为要宣布的RTCDataChannel对象。
  3. 如果通道的[[ReadyState]]为closingclosed,请中止这些步骤。
  4. 将通道的[[ReadyState]]插槽设置为open
  5. 在通道上触发一个名为open的事件。测试1

当要宣布底层数据传输时(另一个对等方创建一个negotiated为未设置或设置为false的通道),未启动创建过程的对等方的用户代理必须对任务排序,以运行以下步骤:

  1. 如果关联的RTCPeerConnection对象的[[IsClosed]]插槽为true,则中止这些步骤。

  2. 创建一个RTCDataChannel,通道。

  3. 让配置成为从另一个对等体接收的信息包,作为建立由WebRTC数据通道协议规范[RTCWEB-DATA-PROTOCOL]描述的底层数据传输的过程的一部分。

  4. 将通道的[[DataChannelLabel]],[[Ordered]],[[MaxPacketLifeTime]],[[MaxRetransmits]],[[DataChannelProtocol]]和[[DataChannelId]]内部插槽初始化为配置中的相应值。

  5. 将通道的[[Negotiated]]内部插槽初始化为false

  6. 根据配置中的整数优先级值初始化通道的[[DataChannelPriority]]内部插槽,根据以下映射:

    | configuration priority value | RTCPriorityType value | | —————————————— | ——————————- | | 0 to 128 | very-low | | 129 to 256 | low | | 257 to 512 | medium | | 513 and greater | high |

  7. 将通道的[[ReadyState]]设置为open(但不要触发open事件)。

    NOTE:这允许在触发open事件之前开始在datachannel事件处理程序内发送消息。

  8. 使用RTCDataChannelEvent接口触发名为datachannel的事件,并将channel属性设置为RTCPeerConnection对象的channel。

  9. 宣布数据通道处于open状态。

通过运行关闭过程,可以以非突然的方式拆除RTCDataChannel对象的底层数据传输。当发生这种情况时,用户代理必须排队任务以运行以下步骤:

  1. 让channel成为其传输已关闭的RTCDataChannel对象。
  2. 除非通过通道的close方法启动该过程,否则将通道的[[ReadyState]]插槽设置为closing
  3. 并行运行以下步骤:
    1. 完成发送channel的所有当前待处理消息。
    2. 遵循为通道的底层传输定义的关闭过程:
      1. 如果是基于SCTP的传输,请按照[RTCWEB-DATA]的6.7节进行操作。
    3. 按照相关步骤渲染通道的数据传输。

RTCDataChannel对象的基础数据传输已关闭时,用户代理必须对任务进行排队以运行以下步骤:

  1. 让channel成为其传输已关闭的RTCDataChannel对象。
  2. 将通道的[[ReadyState]]插槽设置为closed
  3. 如果传输因错误而关闭,则使用RTCErrorEvent接口触发名为error的事件,并在通道中将其errorDetail属性设置为“sctp-failure”
  4. 在通道内发起一个名为close的事件。

在某些情况下,用户代理可能无法创建RTCDataChannel的基础数据传输。例如,数据通道的id可能超出SCTP握手中[RTCWEB-DATA]实现协商的范围。当用户代理确定无法创建RTCDataChannel的基础数据传输时,用户代理必须排队任务以运行以下步骤:

  1. 令channel为RTCDataChannel对象,用户代理无法为其创建底层数据传输。
  2. 将通道的[[ReadyState]]插槽设置为closed
  3. 使用RTCErrorEvent接口触发名为error的事件,并在通道中将errorDetail属性设置为“data-channel-failure”。
  4. 在通道上发起一个名为close的事件。

当通过类型type和数据rawData的底层数据传输接收到RTCDataChannel消息时,用户代理必须排队任务以运行以下步骤:

  1. 令channel为用户代理已收到消息的RTCDataChannel对象。

  2. 如果通道的[[ReadyState]]插槽不为open,则中止这些步骤并丢弃rawData

  3. 通过打开typechannelbinaryType来执行子步骤:

    • 如果type表示rawData是一个字符串:

      令数据为DOMString,表示将rawData解码为UTF-8的结果。

      测试1

    • 如果type表示rawData是二进制而binaryType“blob”

      让data成为包含rawData作为其原始数据源的新Blob对象。

    • 如果type表示rawData是二进制,而binaryType“arraybuffer”

      让data成为一个新的ArrayBuffer对象,包含rawData作为原始数据源。

  4. 使用MessageEvent接口触发名为message的事件,其origin属性初始化为创建通道关联的RTCPeerConnection的文档的原点,并且data属性初始化为通道上的数据。

  1. [Exposed=Window] interface RTCDataChannel : EventTarget {
  2. readonly attribute USVString label;
  3. readonly attribute boolean ordered;
  4. readonly attribute unsigned short? maxPacketLifeTime;
  5. readonly attribute unsigned short? maxRetransmits;
  6. readonly attribute USVString protocol;
  7. readonly attribute boolean negotiated;
  8. readonly attribute unsigned short? id;
  9. readonly attribute RTCPriorityType priority;
  10. readonly attribute RTCDataChannelState readyState;
  11. readonly attribute unsigned long bufferedAmount;
  12. [EnforceRange]
  13. attribute unsigned long bufferedAmountLowThreshold;
  14. attribute EventHandler onopen;
  15. attribute EventHandler onbufferedamountlow;
  16. attribute EventHandler onerror;
  17. attribute EventHandler onclose;
  18. void close ();
  19. attribute EventHandler onmessage;
  20. attribute DOMString binaryType;
  21. void send (USVString data);
  22. void send (Blob data);
  23. void send (ArrayBuffer data);
  24. void send (ArrayBufferView data);
  25. };

属性

USVString类型的label,只读:label属性表示可用于将此RTCDataChannel对象与其他RTCDataChannel对象区分开的标签。允许脚本使用相同的标签创建多个RTCDataChannel对象。获取时,属性必须返回[[DataChannelLabel]]槽的值。测试1

boolean类型ordered,只读:如果RTCDataChannel有序,则ordered属性返回true,如果允许无序传递,则返回false。获取时,属性必须返回[[Ordered]]槽的值。

unsigned short类型的maxPacketLifeTime,只读的,可以为null:maxPacketLifeTime属性返回在不可靠模式下可能发生传输和重传的时间窗口的长度(以毫秒为单位)。获取时,属性必须返回[[MaxPacketLifeTime]]槽的值。

unsigned short类型的maxRetransmits,只读的,可以为null:maxRetransmits属性返回在不可靠模式下尝试的最大重新传输次数。获取时,属性必须返回[[MaxRetransmits]]槽的值。

USVString类型的protocol,只读的:protocol属性返回与此RTCDataChannel一起使用的子协议的名称。获取时,属性必须返回[[DataChannelProtocol]]槽的值。

boolean类型的negotiated,只读的:如果此RTCDataChannel由应用程序协商,则negotiated属性返回true,否则返回false。获取时,属性必须返回[[Negotiated]]插槽的值。

unsigned short类型的id,只读的,可以为null:id属性返回此RTCDataChannel的ID。该值初始为null,如果在创建通道时未提供ID,则返回该值,并且尚未协商SCTP传输的DTLS角色。否则,它将返回由脚本选择的ID或由用户代理根据[RTCWEB-DATA-PROTOCOL]生成的ID。将ID设置为非空值后,它不会更改。获取时,属性必须返回[[DataChannelId]]槽的值。测试2

RTCPriorityType类型的priority,只读:priority属性返回此RTCDataChannel的优先级。优先级由用户代理在通道创建时分配。获取时,属性必须返回[[DataChannelPriority]]槽的值。

RTCDataChannelState类型的readyState,只读的:readyState属性表示RTCDataChannel对象的状态。获取时,属性必须返回[[ReadyState]]槽的值。

unsigned long类型的bufferedAmount,只读的:获取时,bufferedAmount属性必须返回[[BufferedAmount]]槽的值。该属性公开使用send()排队的应用程序数据(UTF-8文本和二进制数据)的字节数。即使数据传输可以并行发生,在当前任务返回事件循环以防止race condition之前,不得减小返回值。该值不包括协议产生的帧开销,或操作系统或网络硬件完成的缓冲。只要[[ReadyState]]插槽打开,[[BufferedAmount]]插槽的值只会随着每次调用send()方法而增加;但是,一旦通道关闭,插槽不会重置为零。当底层数据传输从其队列发送数据时,用户代理必须排队一个任务,该任务随着发送的字节数减少[[BufferedAmount]]。

unsigned long类型的bufferedAmountLowThreshold:bufferedAmountLowThreshold属性设置bufferedAmount被视为低的阈值。当bufferedAmount从此阈值以上减小到等于或低于此阈值时,将触发bufferedamountlow事件。 bufferedAmountLowThreshold在每个新的RTCDataChannel上最初为零,但应用程序可能随时更改其值。

EventHandler类型的onopen:此事件处理程序的事件类型为open

eventHandler类型的onbufferedamountlow:此事件处理程序的事件类型为bufferedamountlow

eventHandler类型的onerror:此事件处理程序的事件类型是RTCErrorEventerrorDetail包含“sctp-failure”,sctpCauseCode包含SCTP Cause Code值,并且message包含SCTP Cause-Specific-Information,可能包含其他文本。

EventHandler类型的onclose:此事件处理程序的事件类型为close

eventHandler类型的onmessage:此事件处理程序的事件类型是message

DOMString类型的binaryType:获取时,binaryType属性必须返回上次设置的值。在设置时,如果新值是字符串“blob”或字符串“arraybuffer”,则将IDL属性设置为此新值。否则,抛出一个SyntaxError。创建RTCDataChannel对象时,必须将binaryType属性初始化为字符串“blob”

此属性控制二进制数据如何向脚本公开。有关更多信息,请参阅[WEBSOCKETS-API]。

方法

close:

关闭RTCDataChannel。无论RTCDataChannel对象是由对等方还是远程对等方创建,都可以调用它。

调用close方法时,用户代理必须执行以下步骤:

  1. 让channel成为即将关闭的RTCDataChannel对象。
  2. 如果通道的[[ReadyState]]插槽为closingclosed,则中止这些步骤。
  3. 将通道的[[ReadyState]]插槽设置为closing
  4. 如果关闭程序尚未开始,请启动它。

send

使用参数类型string对象运行send()算法描述的步骤。测试1

send

使用参数类型Blob对象运行send()算法描述的步骤。

send

使用参数类型ArrayBuffer对象运行send()算法描述的步骤。

send

使用参数类型ArrayBufferView对象运行send()算法描述的步骤。

send()方法被重载,用来处理不同数据参数类型。当该方法的任何版本被调用时,用户代理必须运行下列步骤:

  1. 让channel成为将要发送数据的RTCDataChannel对象。

  2. 如果channel的[ReadyState]插槽不为open,抛出InvalidStateError

  3. 执行对应方法参数类型的子步骤:

    • string对象:

      让data成为byte buffer,表示将方法参数编码为UTF-8的结果。

    • Blob对象:

      让data成为由Blob对象表示的原始数据。

    • ArrayBuffer对象:

      让data成为由ArrayBuffer对象描述的存在buffer中的数据。

    • ArrayBufferView对象:

      让data成为ArrayBufferView对象提到的ArrayBuffer对象描述的buffer中存储的数据。

    NOTE:任何该方法没有重载的数据类型将会导致TypeError。这包括null和undefined。

  4. 如果data的大小超过了channel的关联RTCSctpTransport上的maxMessageSize的值,抛出TypeError

  5. 对在channel的底层数据传输的data进行排队。

    NOTE:实际数据传输是并行的。如果发送数据导致SCTP层级的错误,应用程序将会被通过onerror异步通知。

  6. 增加[BufferedAmount]插槽的值,增加量为data的大小。

  1. dictionary RTCDataChannelInit {
  2. boolean ordered = true;
  3. [EnforceRange]
  4. unsigned short maxPacketLifeTime;
  5. [EnforceRange]
  6. unsigned short maxRetransmits;
  7. USVString protocol = "";
  8. boolean negotiated = false;
  9. [EnforceRange]
  10. unsigned short id;
  11. RTCPriorityType priority = "low";
  12. };

字典RTCDataChannelInit成员

boolean类型的ordered,默认为true:如果设置为false,则允许数据不按顺序传送。默认值为true,保证数据按顺序传递。

unsigned short类型的maxPacketLifeTime:限制通道在未确认的情况下传输或重新传输数据的时间(以毫秒为单位)。如果该值超过用户代理支持的最大值,则可以限制该值。测试1

unsigned short类型的maxRetransmits:如果未成功传递,则限制通道重新传输数据的次数。如果该值超过用户代理支持的最大值,则可以限制该值。

USVString类型的protocol,默认为“”:用于此通道的子协议名称。

boolean类型的negotiated,默认为false:默认值false指示用户代理在带内通告通道并指示另一个对等方分派相应的RTCDataChannel对象。如果设置为true,则由应用程序协商通道并在另一个对等方创建具有相同ID的RTCDataChannel对象。

NOTE:如果设置为true,则应用程序还必须注意不要发送消息,直到另一个对等方创建了一个数据通道来接收它。在没有关联数据通道的SCTP流上接收消息是未定义的行为,可能会以静默方式丢弃。只要两个端点在第一个提议/应答交换完成之前创建其数据通道,就不可能实现这一点。

unsigned short类型的id:重写此通道的默认ID选择。

RTCPriorityType类型的priority,默认为low:此通道的优先级。

  1. enum RTCDataChannelState {
  2. "connecting",
  3. "open",
  4. "closing",
  5. "closed"
  6. };
RTCDataChannelState枚举描述
connecting 用户代理正在尝试建立底层数据传输。这是RTCDataChannel对象的初始状态,无论是使用createDataChannel创建,还是作为RTCDataChannelEvent的一部分调度。
open 建立基础数据传输并且可以进行通信。
closing 关闭底层数据传输的过程已经开始。
closed 底层数据传输已关闭或无法建立。