6.2 RTCDataChannel

The RTCDataChannel interface represents a bi-directional data channel between two peers. An RTCDataChannel is created via a factory method on an RTCPeerConnection object. The messages sent between the browsers are described in [RFC8831] and [RFC8832].

There are two ways to establish a connection with RTCDataChannel. The first way is to simply create an RTCDataChannel at one of the peers with the negotiated RTCDataChannelInit dictionary member unset or set to its default value false. This will announce the new channel in-band and trigger an RTCDataChannelEvent with the corresponding RTCDataChannel object at the other peer. The second way is to let the application negotiate the RTCDataChannel. To do this, create an RTCDataChannel object with the negotiated RTCDataChannelInit dictionary member set to true, and signal out-of-band (e.g. via a web server) to the other side that it SHOULD create a corresponding RTCDataChannel with the negotiated RTCDataChannelInit dictionary member set to true and the same id. This will connect the two separately created RTCDataChannel objects. The second way makes it possible to create channels with asymmetric properties and to create channels in a declarative way by specifying matching ids.

Each RTCDataChannel has an associated underlying data transport that is used to transport actual data to the other peer. In the case of SCTP data channels utilizing an RTCSctpTransport (which represents the state of the SCTP association), the underlying data transport is the SCTP stream pair. The transport properties of the underlying data transport, such as in order delivery settings and reliability mode, are configured by the peer as the channel is created. The properties of a channel cannot change after the channel has been created. The actual wire protocol between the peers is specified by the WebRTC DataChannel Protocol specification [RFC8831].

An RTCDataChannel can be configured to operate in different reliability modes. A reliable channel ensures that the data is delivered at the other peer through retransmissions. An unreliable channel is configured to either limit the number of retransmissions ( maxRetransmits ) or set a time during which transmissions (including retransmissions) are allowed ( maxPacketLifeTime ). These properties can not be used simultaneously and an attempt to do so will result in an error. Not setting any of these properties results in a reliable channel.

An RTCDataChannel, created with createDataChannel or dispatched via an RTCDataChannelEvent, MUST initially be in the “connecting“ state. When the RTCDataChannel object’s underlying data transport is ready, the user agent MUST announce the RTCDataChannel as open.

6.2.1 Creating a data channel

To create an RTCDataChannel, run the following steps:

  1. Let channel be a newly created RTCDataChannel object.

  2. Let channel have a [[ReadyState]] internal slot initialized to “connecting“.

  3. Let channel have a [[BufferedAmount]] internal slot initialized to 0.

  4. Let channel have internal slots named [[DataChannelLabel]], [[Ordered]], [[MaxPacketLifeTime]], [[MaxRetransmits]], [[DataChannelProtocol]], [[Negotiated]], and [[DataChannelId]].

  5. Return channel.

6.2.2 Announcing a data channel as open

When the user agent is to announce an RTCDataChannel as open, the user agent MUST queue a task to run the following steps:

  1. If the associated RTCPeerConnection object’s [[IsClosed]] slot is true, abort these steps.

  2. Let channel be the RTCDataChannel object to be announced.

  3. If channel.[[ReadyState]] is “closing“ or “closed“, abort these steps.

  4. Set channel.[[ReadyState]] to “open“.

  5. Fire an event named open at channel.

6.2.3 Announcing a data channel instance

When an underlying data transport is to be announced (the other peer created a channel with negotiated unset or set to false), the user agent of the peer that did not initiate the creation process MUST queue a task to run the following steps:

  1. Let connection be the RTCPeerConnection object associated with the underlying data transport.

  2. If connection.[[IsClosed]] is true, abort these steps.

  3. Create an RTCDataChannel, channel.

  4. Let configuration be an information bundle received from the other peer as a part of the process to establish the underlying data transport described by the WebRTC DataChannel Protocol specification [RFC8832].

  5. Initialize channel.[[DataChannelLabel]], [[Ordered]], [[MaxPacketLifeTime]], [[MaxRetransmits]], [[DataChannelProtocol]], and [[DataChannelId]] internal slots to the corresponding values in configuration.

  6. Initialize channel.[[Negotiated]] to false.

  7. Set channel.[[ReadyState]] to “open“ (but do not fire the open event, yet).

    Note

    This allows to start sending messages inside of the datachannel event handler prior to the open event being fired.

  8. Fire an event named datachannel using the RTCDataChannelEvent interface with the channel attribute set to channel at connection.

  9. Announce the data channel as open.

6.2.4 Closing procedure

An RTCDataChannel object’s underlying data transport may be torn down in a non-abrupt manner by running the closing procedure. When that happens the user agent MUST queue a task to run the following steps:

  1. Let channel be the RTCDataChannel object whose underlying data transport was closed.

  2. Unless the procedure was initiated by channel.close, set channel.[[ReadyState]] to “closing“ and fire an event named closing at channel.

  3. Run the following steps in parallel:

    1. Finish sending all currently pending messages of the channel.

    2. Follow the closing procedure defined for the channel’s underlying data transport :

      1. In the case of an SCTP-based transport, follow [RFC8831], section 6.7.
    3. Render the channel’s data transport closed by following the associated procedure.

6.2.5 Announcing a data channel as closed

When an RTCDataChannel object’s underlying data transport has been closed, the user agent MUST queue a task to run the following steps:

  1. Let channel be the RTCDataChannel object whose underlying data transport was closed.

  2. If channel.[[ReadyState]] is “closed“, abort these steps.

  3. Set channel.[[ReadyState]] to “closed“.

  4. If the transport was closed with an error, fire an event named error using the RTCErrorEvent interface with its errorDetail attribute set to “sctp-failure“ at channel.

  5. Fire an event named close at channel.

6.2.6 Error on creating data channels

In some cases, the user agent may be unable to create an RTCDataChannel ‘s underlying data transport. For example, the data channel’s id may be outside the range negotiated by the [RFC8831] implementations in the SCTP handshake. When the user agent determines that an RTCDataChannel‘s underlying data transport cannot be created, the user agent MUST queue a task to run the following steps:

  1. Let channel be the RTCDataChannel object for which the user agent could not create an underlying data transport.

  2. Set channel.[[ReadyState]] to “closed“.

  3. Fire an event named error using the RTCErrorEvent interface with the errorDetail attribute set to “data-channel-failure“ at channel.

  4. Fire an event named close at channel.

6.2.7 Receiving messages on a data channel

When an RTCDataChannel message has been received via the underlying data transport with type type and data rawData, the user agent MUST queue a task to run the following steps:

  1. Let channel be the RTCDataChannel object for which the user agent has received a message.

  2. Let connection be the RTCPeerConnection object associated with channel.

  3. If channel.[[ReadyState]] is not “open“, abort these steps and discard rawData.

  4. Execute the sub step by switching on type and channel.binaryType:

    • If type indicates that rawData is a string:

      Let data be a DOMString that represents the result of decoding rawData as UTF-8.

    • If type indicates that rawData is binary and binaryType is "blob":

      Let data be a new Blob object containing rawData as its raw data source.

    • If type indicates that rawData is binary and binaryType is "arraybuffer":

      Let data be a new ArrayBuffer object containing rawData as its raw data source.

  5. Fire an event named message using the MessageEvent interface with its origin attribute initialized to the serialization of an origin of connection.[[DocumentOrigin]], and the data attribute initialized to data at channel.

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

Attributes

label of type USVString, readonly

The label attribute represents a label that can be used to distinguish this RTCDataChannel object from other RTCDataChannel objects. Scripts are allowed to create multiple RTCDataChannel objects with the same label. On getting, the attribute MUST return the value of the [[DataChannelLabel]] slot.

ordered of type boolean, readonly

The ordered attribute returns true if the RTCDataChannel is ordered, and false if out of order delivery is allowed. On getting, the attribute MUST return the value of the [[Ordered]] slot.

maxPacketLifeTime of type unsigned short, readonly, nullable

The maxPacketLifeTime attribute returns the length of the time window (in milliseconds) during which transmissions and retransmissions may occur in unreliable mode. On getting, the attribute MUST return the value of the [[MaxPacketLifeTime]] slot.

maxRetransmits of type unsigned short, readonly, nullable

The maxRetransmits attribute returns the maximum number of retransmissions that are attempted in unreliable mode. On getting, the attribute MUST return the value of the [[MaxRetransmits]] slot.

protocol of type USVString, readonly

The protocol attribute returns the name of the sub-protocol used with this RTCDataChannel. On getting, the attribute MUST return the value of the [[DataChannelProtocol]] slot.

negotiated of type boolean, readonly

The negotiated attribute returns true if this RTCDataChannel was negotiated by the application, or false otherwise. On getting, the attribute MUST return the value of the [[Negotiated]] slot.

id of type unsigned short, readonly, nullable

The id attribute returns the ID for this RTCDataChannel. The value is initially null, which is what will be returned if the ID was not provided at channel creation time, and the DTLS role of the SCTP transport has not yet been negotiated. Otherwise, it will return the ID that was either selected by the script or generated by the user agent according to [RFC8832]. After the ID is set to a non-null value, it will not change. On getting, the attribute MUST return the value of the [[DataChannelId]] slot.

readyState of type RTCDataChannelState, readonly

The readyState attribute represents the state of the RTCDataChannel object. On getting, the attribute MUST return the value of the [[ReadyState]] slot.

bufferedAmount of type unsigned long, readonly

The bufferedAmount attribute MUST, on getting, return the value of the [[BufferedAmount]] slot. The attribute exposes the number of bytes of application data (UTF-8 text and binary data) that have been queued using send(). Even though the data transmission can occur in parallel, the returned value MUST NOT be decreased before the current task yielded back to the event loop to prevent race conditions. The value does not include framing overhead incurred by the protocol, or buffering done by the operating system or network hardware. The value of the [[BufferedAmount]] slot will only increase with each call to the send() method as long as the [[ReadyState]] slot is “open“; however, the slot does not reset to zero once the channel closes. When the underlying data transport sends data from its queue, the user agent MUST queue a task that reduces [[BufferedAmount]] with the number of bytes that was sent.

bufferedAmountLowThreshold of type unsigned long

The bufferedAmountLowThreshold attribute sets the threshold at which the bufferedAmount is considered to be low. When the bufferedAmount decreases from above this threshold to equal or below it, the bufferedamountlow event fires. The bufferedAmountLowThreshold is initially zero on each new RTCDataChannel, but the application may change its value at any time.

onopen of type EventHandler

The event type of this event handler is open.

onbufferedamountlow of type EventHandler

The event type of this event handler is bufferedamountlow.

onerror of type EventHandler

The event type of this event handler is RTCErrorEvent. errorDetail contains “sctp-failure”, sctpCauseCode contains the SCTP Cause Code value, and message contains the SCTP Cause-Specific-Information, possibly with additional text.

onclosing of type EventHandler

The event type of this event handler is closing.

onclose of type EventHandler

The event type of this event handler is close.

onmessage of type EventHandler

The event type of this event handler is message.

binaryType of type BinaryType

The binaryType attribute MUST, on getting, return the value to which it was last set. On setting, if the new value is either the string "blob" or the string "arraybuffer", then set the IDL attribute to this new value. Otherwise, throw a SyntaxError. When an RTCDataChannel object is created, the binaryType attribute MUST be initialized to the string "blob".

This attribute controls how binary data is exposed to scripts. See Web Socket’s binaryType.

Methods

close

Closes the RTCDataChannel. It may be called regardless of whether the RTCDataChannel object was created by this peer or the remote peer.

When the close method is called, the user agent MUST run the following steps:

  1. Let channel be the RTCDataChannel object which is about to be closed.

  2. If channel.[[ReadyState]] is “closing“ or “closed“, then abort these steps.

  3. Set channel.[[ReadyState]] to “closing“.

  4. If the closing procedure has not started yet, start it.

send

Run the steps described by the send() algorithm with argument type string object.

send

Run the steps described by the send() algorithm with argument type Blob object.

send

Run the steps described by the send() algorithm with argument type ArrayBuffer object.

send

Run the steps described by the send() algorithm with argument type ArrayBufferView object.

The send() method is overloaded to handle different data argument types. When any version of the method is called, the user agent MUST run the following steps:

  1. Let channel be the RTCDataChannel object on which data is to be sent.

  2. If channel.[[ReadyState]] is not “open“, throw an InvalidStateError.

  3. Execute the sub step that corresponds to the type of the methods argument:

    • string object:

      Let data be a byte buffer that represents the result of encoding the method’s argument as UTF-8.

    • Blob object:

      Let data be the raw data represented by the Blob object.

      Note

      Although the actual retrieval of data from a Blob object can happen asynchronously, the user agent will make sure to queue the data on the channel’s underlying data transport in the same order as the send method is called. The byte size of data needs to be known synchronously.

    • ArrayBuffer object:

      Let data be the data stored in the buffer described by the ArrayBuffer object.

    • ArrayBufferView object:

      Let data be the data stored in the section of the buffer described by the ArrayBuffer object that the ArrayBufferView object references.

    Note

    Any data argument type this method has not been overloaded with will result in a TypeError. This includes null and undefined.

  4. If the byte size of data exceeds the value of maxMessageSize on channel’s associated RTCSctpTransport, throw a TypeError.

  5. Queue data for transmission on channel’s underlying data transport. If queuing data is not possible because not enough buffer space is available, throw an OperationError.

    Note

    The actual transmission of data occurs in parallel. If sending data leads to an SCTP-level error, the application will be notified asynchronously through onerror.

  6. Increase the value of the [[BufferedAmount]] slot by the byte size of data.

  1. WebIDLdictionary RTCDataChannelInit {
  2. boolean ordered = true;
  3. [EnforceRange] unsigned short maxPacketLifeTime;
  4. [EnforceRange] unsigned short maxRetransmits;
  5. USVString protocol = "";
  6. boolean negotiated = false;
  7. [EnforceRange] unsigned short id;
  8. };

Dictionary RTCDataChannelInit Members

ordered of type boolean, defaulting to true

If set to false, data is allowed to be delivered out of order. The default value of true, guarantees that data will be delivered in order.

maxPacketLifeTime of type unsigned short

Limits the time (in milliseconds) during which the channel will transmit or retransmit data if not acknowledged. This value may be clamped if it exceeds the maximum value supported by the user agent.

maxRetransmits of type unsigned short

Limits the number of times a channel will retransmit data if not successfully delivered. This value may be clamped if it exceeds the maximum value supported by the user agent.

protocol of type USVString, defaulting to ""

Subprotocol name used for this channel.

negotiated of type boolean, defaulting to false

The default value of false tells the user agent to announce the channel in-band and instruct the other peer to dispatch a corresponding RTCDataChannel object. If set to true, it is up to the application to negotiate the channel and create an RTCDataChannel object with the same id at the other peer.

Note

If set to true, the application must also take care to not send a message until the other peer has created a data channel to receive it. Receiving a message on an SCTP stream with no associated data channel is undefined behavior, and it may be silently dropped. This will not be possible as long as both endpoints create their data channel before the first offer/answer exchange is complete.

id of type unsigned short

Sets the channel ID when negotiated is true. Ignored when negotiated is false.

  1. WebIDLenum RTCDataChannelState {
  2. "connecting",
  3. "open",
  4. "closing",
  5. "closed"
  6. };
RTCDataChannelState Enumeration description
connecting

The user agent is attempting to establish the underlying data transport. This is the initial state of an RTCDataChannel object, whether created with createDataChannel, or dispatched as a part of an RTCDataChannelEvent.

open

The underlying data transport is established and communication is possible.

closing

The procedure to close down the underlying data transport has started.

closed

The underlying data transport has been closed or could not be established.