Using WebRTC data channels
In this guide, we'll examine how to add a data channel to a peer connection, which can then be used to securely exchange arbitrary data; that is, any kind of data we wish, in any format we choose.
Note:Since all WebRTC components are required to use encryption, any data transmitted on anRTCDataChannel
is automatically secured using Datagram Transport Layer Security (DTLS). SeeSecurity below for more information.
Creating a data channel
The underlying data transport used by theRTCDataChannel
can be created in one of two ways:
- Let WebRTC create the transport and announce it to the remote peer for you (by causing it to receive a
datachannel
event). This is the easy way, and works for a wide variety of use cases, but may not be flexible enough for your needs. - Write your own code to negotiate the data transport and write your own code to signal to the other peer that it needs to connect to the new channel.
Let's look at each of these cases, starting with the first, which is the most common.
Automatic negotiation
Often, you can allow the peer connection to handle negotiating theRTCDataChannel
connection for you. To do this, callcreateDataChannel()
without specifying a value for thenegotiated
property, or specifying the property with a value offalse
. This will automatically trigger theRTCPeerConnection
to handle the negotiations for you, causing the remote peer to create a data channel and linking the two together across the network.
TheRTCDataChannel
object is returned immediately bycreateDataChannel()
; you can tell when the connection has been made successfully by watching for theopen
event to be sent to theRTCDataChannel
.
let dataChannel = pc.createDataChannel("MyApp Channel");dataChannel.addEventListener("open", (event) => { beginTransmission(dataChannel);});
Manual negotiation
To manually negotiate the data channel connection, you need to first create a newRTCDataChannel
object using thecreateDataChannel()
method on theRTCPeerConnection
, specifying in the options anegotiated
property set totrue
. This signals to the peer connection to not attempt to negotiate the channel on your behalf.
Then negotiate the connection out-of-band, using a web server or other means. This process should signal to the remote peer that it should create its ownRTCDataChannel
with thenegotiated
property also set totrue
, using the sameid
. This will link the two objects across theRTCPeerConnection
.
let dataChannel = pc.createDataChannel("MyApp Channel", { negotiated: true,});dataChannel.addEventListener("open", (event) => { beginTransmission(dataChannel);});requestRemoteChannel(dataChannel.id);
In this code snippet, the channel is created withnegotiated
set totrue
, then a function calledrequestRemoteChannel()
is used to trigger negotiation, to create a remote channel with the same ID as the local channel.
Doing this lets you create data channels with each peer using different properties, and to create channels declaratively by using the same value forid
.
Buffering
WebRTC data channels support buffering of outbound data. This is handled automatically. While there's no way to control the size of the buffer, you can learn how much data is currently buffered, and you can choose to be notified by an event when the buffer starts to run low on queued data. This makes it easy to write efficient routines that make sure there's always data ready to send without over-using memory or swamping the channel completely.
Understanding message size limits
You should keep message sizes moderately small. While most modern browsers support sending messages of at least 256 kilobytes, there are downsides to sending large messages, especially when message interleaving is not available. Without message interleaving (as defined inRFC 8260), sending a large message on one data channel can causehead-of-line blocking, which in turn can negatively affect the latency of messages on other data channels.
The maximum message size can be negotiated using themax-message-size
SDP attribute, as defined inRFC 8841. This attribute allows each peer to declare the maximum size of an SCTP user message that it is willing to receive. By negotiating this value, endpoints can avoid sending messages that are larger than the other peer can handle. If themax-message-size
attribute is not present in the SDP, a default value of 64 kilobytes is assumed. A value of 0 indicates that the endpoint can handle messages of any size, limited only by available memory.
Security
All data transferred using WebRTC is encrypted. In the case ofRTCDataChannel
, the encryption used is Datagram Transport Layer Security (DTLS), which is based onTransport Layer Security (TLS). Since TLS is used to secure every HTTPS connection, any data you send on a data channel is as secure as any other data sent or received by the user's browser.
More fundamentally, since WebRTC is a peer-to-peer connection between two user agents, the data never passes through the web or application server. This reduces opportunities to have the data intercepted.