2

I'm trying to follow this example to create DataChannel.

For the signaling I am using websockets, which behave like so:

User A joins

User B joins
User B asks User A to create an offer
-> A opens datachannel before creating an offer
-> A sets his local description
User A sends his offer to User B 
-> B answers the offer
-> B sets local and remote description 
User B sends A his local description

(User B doesn't directly send message to user A, this is done through websockets with an intermediary server which holds the websocket sessions, skipping that part for sake of simplicity)

The creating offer code for user A is the following:

let pc = new RTCPeerConnection({
    iceServers: [
        {
            urls: "stun:stun.l.google.com:19302",
        }
    ]
});
let dc = pc.createDataChannel("Base");
dc.onbufferedamountlow = function(){
console.error("dataChannel.onbufferedamountlow");
};
dc.onclose = function(){
    console.error("dataChannel.onclose");
};
dc.onerror = function(){
    console.error("dataChannel.onerror");
};
dc.onmessage = function(){
    console.error("dataChannel.onmessage");
};
dc.onopen = function(){
    console.error("dataChannel.onopen");
};

let offer = await pc.createOffer();
await pc.setLocalDescription(offer);
let offerString = JSON.stringify(pc.localDescription); //Is sent to B

The complete code for user B is the following:

let pc = new RTCPeerConnection({
    iceServers: [
        {
            urls: "stun:stun.l.google.com:19302",
        }
    ]
});
await pc.setRemoteDescription(new RTCSessionDescription(offer)); //From A
let answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
let answerString = JSON.stringify(pc.localDescription); //Returns to A

So when A receives B's answer, it just:

await pc.setRemoteDescription(new RTCSessionDescription(answer));

Object of A:

A user log

Object of B:

enter image description here

Firefox about:webrtc errors

What I have also tried without success:

-opening the data channel after both users have established connections, nothing, none of the events get fired, some updates on this:

  1. after creating the Data Channel on both, I always see readyState as connecting... on both clients... picture of RTCPeer data channel error

-opening data channel on B while A is still waiting for B's response back, Data Channel onclose event is fired without even firing the open event...

-using https://test.webrtc.org/ to test, this is the result:

enter image description here

-I've been also looking for other issues or similar to mine, forums, blogs etc... all answers which range from 2 to 5 years old seem way outdated and not working...

-creating the channel on both sides like so:

pc.createDataChannel("Test", {
    id: 1,
    negotiated: true,
})

Leads to OperationError: Id is in use on one of the clients. How can I join a channel by Its ID if the DOC states this:

Alternatively (true), they can be negotiated out of-band, where both sides call createDataChannel with an agreed-upon id.

If I must join a channel by an ID but while creating the object I get that Id is in use, wth how do I join it?

If I don't specify an id I get TypeError: id is required when negotiated is true

While the doc says:

ID: Optional - An 16-bit numeric ID for the channel; permitted values are 0-65534. If you don't include this option, the user agent will select an ID for you.

  1. Adding await pc.addIceCandidate(); or await pc.addIceCandidate(null);, after setting both connections Local and Remote description.

  2. Started my own TURN server with both TCP and UDP open, same result as with Google's STUN server.

  3. Tried using both STUN and TURN servers in the iceServer.

  4. Tried both Firefox and Chrome latest versions.

Questions:

1) When must the data channel start opening? After both clients have done negociation and pc.connectionState is stable? Right after creating the connection object? Before or after setting local description ?

Alpha2k
  • 2,212
  • 7
  • 38
  • 65

1 Answers1

-1

The problem is you need exchange the ICE information over the signal (not just the SDP information).

ice is that tell remote peer know how to connect, SDP is like what content i can serve.

Community
  • 1
  • 1
ssskip
  • 259
  • 1
  • 6
  • Ice doesn't seem to work as the event on add candidate, the candidate is always null... – Alpha2k Apr 11 '20 at 12:12
  • @Alpha2k the event.candidate is null once the ice Finished. – ssskip Apr 11 '20 at 13:57
  • always null shouldn't be happen if you are doing right or your network can do p2p without turn server, https://stackoverflow.com/questions/60956134/webrtc-peer-connection-blocked-by-uae/60992757#60992757 @Alpha2k – ssskip Apr 11 '20 at 13:59
  • all the necessary ports are open, as for the null: https://stackoverflow.com/questions/55840870/addicecandidate-with-argument-null-result-in-error If the event's candidate property is null, ICE gathering has finished. – Alpha2k Apr 11 '20 at 17:55