4
votes

I'm trying to understand how WebRTC works, mainly for using only DataChannel for game-networking experience. And this is what I've made so far. It gather ICE cadidates. I have two questions.

  1. Does offer need to be done for gathering ICE?
  2. Why offerToReceiveAudio or offerToReceiveVideo needs to be set true, I'm gonna only use Datachannel. (without one of this option set to true, ICE doesn't appears) (solved, see EDIT bellow)

Here goes a fiddle:

https://jsfiddle.net/t431a815/9/

and code:

var iceServers = [

] 

var config = {
  iceServers: iceServers,
  iceTransportPolicy: "all",
  rtcpMuxPolicy: 'negotiate'
};

var pcConstraints = {};
var offerOptions = {offerToReceiveAudio: true};

pcConstraints.optional = [{'googIPv6': true}]; // Whether we gather IPv6 candidates.

var pc = new RTCPeerConnection(config, pcConstraints);
pc.onicecandidate = iceCallback;
pc.createOffer(
  offerOptions
).then(
  gotDescription,
  error
);

function gotDescription(desc) {
  console.log("OFFER DESC:", desc);
  pc.setLocalDescription(desc);
}

function error() {
  console.log("sth goes wrong", arguments);
}

function iceCallback(event) {
  console.log("ICE!", JSON.stringify(event.candidate));
}

EDIT:

found solution but it's weird, you just need to create one datachannel before making offer, then it works with offerToReceiveAudio: false, offerToReceiveVideo: false

var offererDataChannel = pc.createDataChannel('channel', {});

but why? What if I want to create it later?

1

1 Answers

3
votes

You need to send something. Otherwise it's like shipping a box with nothing in it, or streaming a stream with no content. No benefit.

All the effort in establishing a peer connection is in negotiating working IP+port pairs for each thing that needs to be sent. E.g. a pair for video, a pair for audio, and/or a pair for data.

This is most easily visualized by each piece needing its own "m-line" in the offer SDP.

var pc = new RTCPeerConnection();

pc.createDataChannel("dummy");
pc.createOffer().then(({sdp}) =>
   sdp.split('\r\n').filter(s => s.startsWith('m=')).map(s => console.log(s)));
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

Adding video or audio later (or adding data if you don't have it initially) requires re-negotiation, which has the same cost under the hood as the initial negotiation.

The exception is additional data channels, which all get multiplexed over the same port, without needing renegotiation, because, you know, you have a data channel between the peers now.

In other words, if you want to add data channels later, make a dummy one upfront. All subsequent data channels are then basically free. Conversely, if you want the cost later, connect later.