WebRTC data channel: signaling and connecting (#4)

Jan. 27, 2015

Let’s pick things up where we last left off - after we went over the key WebRTC data channel (DC) characteristics in the previous post, today we’re going to explore one specific topic: signaling and establishing a connection.

[Go to Post#1: WebRTC Data Channel: An Overview]

Creating a data channel

The developer creates a data channel by asking the PeerConnection to create it for them. The developer should provide only the name for the data channel and an optional list of parameters. The name can be any valid string that has a meaning in respect to the application. In fact, many data channels can be created: two, three or more depending on the needs of the application. Each channel should, of course, have its unique name. If more than one channel is created, then the channels are multiplexed together. This allows for an efficient handling of multiple channels. Using more than one channel also helps in dealing with problems such as head-of-line (HOL) blocking, in addition to reducing complexity in certain applications.

A pair of messages is exchanged between peers once these steps have been performed: 1. All data channels have been added; 2. Signaling has been performed, and 3. A connection between the two WebRTC instances has been opened successfully. These messages are sent inbound, meaning directly from the first instance to the second and from the second to the first. These messages are not part of signaling. They carry information about the number of data channels and their names for each of the peers.

When a WebRTC instance receives such a message, it automatically adds all the data channels that it does not already have. For example, if the first peer creates a data channel called “mychannel” and the second does not create any data channels at all, then the first instance will receive a message that contains an empty list and will not do anything but the second will receive a message that contains the information for the “mychannel” data channel and WebRTC will automatically create a DC with the same name and notify the application. In effect, when a developer creates a data channel, the other side is “magically” notified of this new channel. This has the advantage of being very simple to use, especially for developers who are just starting with WebRTC. The disadvantage of this automation is the inbound exchange of the pair of messages, which takes time. Plus, in many cases it is completely unnecessary because the number and names of the data channels are known in advance as typically the number of data channels and their names are part of the application protocol.


Usually, an application creates just one or two DCs. In these cases, the initial set-up of the data channel(s) can be sped up by setting the negotiated attribute to “true.” This attribute can be specified as part of the list of parameters that is passed to the DC constructor. It is a property of the DC and should be set explicitly for each one. If the negotiated option is set, then the pair of messages that was just described will not be sent. This means that if a data channel with the same name is not manually created on the other side then the data channel will remain in a state where it will be only “half-connected” and no data can be transferred over it. To sum up: setting the “negotiated” property to “true” speeds up the creation and initialization of the data channel but also requires the developer to manually create a matching data channel on the other side with the same name. Failure to do so can create nasty, hard-to-find bugs.

There is an interesting oddity to the default configuration of WebRTC. By default it tries to create an audio channel. This is fine for most WebRTC applications that use the video/audio channels anyway but it’s unnecessary for an application that uses just the data channel. If the default options are used but just data channels are created then WebRTC gets confused why you want audio (the default configuration) but you don’t create a media channel. It will eventually figure out the problem but it’s a good idea to save it the trouble of doing so by just instructing WebRTC not to offer an audio channel. This is done by setting the “OfferToReceiveAudio” option to “false”. This is an option of the PeerConnection and not of the DC.

A word of caution on the subject of signaling. One should be careful with trickle ICE and should not mess with it. That is, do not buffer messages and then send them in a bunch but send them as soon as the system gives them to the app.

The next article will explore the question of message sizes and sending large amounts of data as fast as possible.

[Go to Post #5: WebRTC data channel: Optimum message size]

Author: Svetlin Mladenov, Chief Architect