How are data feeds negotiated between two peers using WebRTC?

WebRTC interface RTCPeerConnection

has createDataChannel

and ondatachannel

event handler. How do they interact? How do I create a single data channel that can be used to send / receive data between two peers?

In addition, the constructor RTCDataChannelInit

has a field negotiated

that is set to by default false

and says it is in the channel declared in the frequency band. What happens if it's installed on true

?

+3


source to share


1 answer


First: to create any data channel, peers must exchange an SDP offer / response that negotiates the properties of the SCTP connection used by all data channels. This doesn't happen by default; you must call createDataChannel

before calling createOffer

for an offer to contain this SCTP information (the "m = application" section in the SDP).

If you don't, the data link state will be stuck forever <<22>.

From this point of view, there are two ways to negotiate a data channel between two peers:

In-band negotiation

This is what happens by default if the field is negotiated

not set to true

. One peer calls createDataChannel

and the other connects to ondatachannel

EventHandler

. How it works:

  • Peer A calls createDataChannel

    .
  • The usual offer / response is executed.
  • Once the SCTP connection is complete, a message is sent within range from peer A to peer B to signal the existence of a data link.
  • The Peer B ondatachannel

    EventHandler

    is called with a new data channel created from the in-band message. It has the same properties as the data channel created by Peer A, and these data channels can now be used to send data bi-directionally.

The advantage of this approach is that data channels can be dynamically created at any time without an application requiring additional signaling.

Out-of-band negotiation

Data channels can also be negotiated out of range. With this approach, instead of calling createDataChannel

on one side and listening ondatachannel

on the other side, the application simply calls createDataChannel

on both sides.

  • Peer-to-peer call A createDataChannel({negotiated: true, id: 0})

  • Peer B also calls createDataChannel({negotiated: true, id: 0})

    .
  • The usual offer / response is executed.
  • Once the SCTP connection is established, the channels will be instantly used ( readyState

    will change to open

    ). They are matched by an identifier that is the base identifier of the SCTP stream.

The advantage of this approach is that since no in-band message is required to create a data channel on Peer B, the channel will be used earlier. It also makes the application code simpler as you don't even need to worry about ondatachannel

.



So, for applications that only use a fixed number of data channels, this approach is recommended .

Note that the identifier you choose is not just an arbitrary value . It represents the base SCTP stream ID based on 0. And these IDs can only reach the number of SCTP streams negotiated with the WebRTC implementation. Thus, if you use too high an ID, your data feed will not work.

What about native apps?

If you use the native webrtc library instead of the JS API, it works the same; things just have different names.

C ++:

  • PeerConnectionObserver::OnDataChannel

  • DataChannelInit::negotiated

  • DataChannelInit::id

Java:

  • PeerConnection.Observer.onDataChannel

  • DataChannel.Init.negotiated

  • DataChannel.Init.id

Obj-C:

  • RTCPeerConnectionDelegate::didOpenDataChannel

  • RTCDataChannelConfiguration::isNegotiated

  • RTCDataChannelConfiguration::channelId

+7


source







All Articles