vardius
vardius

Reputation: 6556

Why my WebRTC connection works only at local network?

I am experimenting with WebRTC, simply building chat on a data channel. I have a problem that the chat works when both peers are connected on the same local network. Where peers try to connect from different networks (I have been testing this with 2 computers one connected to my home Internet network and the other one via my phone wifi router).

The behavior of chat seems to be fine, offer and answer are sent correctly via signaling server. And with the same signaling server the ice candidate is sent as well.

peer.onicecandidate = (iceEvent: RTCPeerConnectionIceEvent) => {
  if (iceEvent.candidate) {
    const message: ConnectionEvent = {
      type: ConnectionEventType.CANDIDATE,
      caller: null,
      callee: event.caller,
      room: event.room,
      data: iceEvent.candidate,
    };

    ws.send(message);
  } else {
    // All ICE candidates have been sent
  }
};

So the peer that creates offer sends only ONE ice candidate and i think this is the problem becouse the peer creating answer sends TWO ice candidates.

What can be a problem here? When should i call addIceCandidate ?

This is example console log with sent and recieved data

Peer offering connection:

sent: CONNECT Object {type: "CONNECT", caller: Object, callee: null, room: Object, data: null}

recieved: CONNECT Object {type: "CONNECT", caller: Object, callee: null, room: Object, data: null}

sent: OFFER Object {type: "OFFER", caller: Object, callee: Object, room: Object, data: Object}

sent: CANDIDATE Object {type: "CANDIDATE", caller: Object, callee: Object, room: Object, data: Object}

sent: CANDIDATE Object {type: "CANDIDATE", caller: Object, callee: Object, room: Object, data: Object}

recieved: ANSWER Object {type: "ANSWER", caller: Object, callee: Object, room: Object, data: Object}

recieved: CANDIDATE Object {type: "CANDIDATE", caller: Object, callee: Object, room: Object, data: Object}

Peer creating answer:

sent: CONNECT Object {type: "CONNECT", caller: Object, callee: null, room: Object, data: null}

recieved: OFFER Object {type: "OFFER", caller: Object, callee: Object, room: Object, data: Object}

recieved: CANDIDATE Object {type: "CANDIDATE", caller: Object, callee: Object, room: Object, data: Object}

recieved: CANDIDATE Object {type: "CANDIDATE", caller: Object, callee: Object, room: Object, data: Object}

sent: ANSWER Object {type: "ANSWER", caller: Object, callee: Object, room: Object, data: Object}

sent: CANDIDATE Object {type: "CANDIDATE", caller: Object, callee: Object, room: Object, data: Object}

Upvotes: 6

Views: 7329

Answers (3)

Neeraj Sharma
Neeraj Sharma

Reputation: 56

I agree with the answer provided above but STUN fails when symmetric natting comes across.

In order to have this worked seamlessly, You need to have TURN server in place, which works in symmetric natting as well.

The implementation remains same but it works on TCP protocol which implies it tracks every packet transmitted. The implementation is as follows:

var servers = { 'iceServers':[{ 'urls': 'turn:<turn-server-address>' }] };
connection = new RTCPeerConnection(servers);

What this implantation does is it sends TCP encapsulated turn requests which are further resolved and sent across to the recipient.

Upvotes: 1

visibleman
visibleman

Reputation: 3315

Depending on how routers and or firewalls are set up, you might also need to configure both STUN and TURN.

See Introduction to WebRTC protocols to understand the difference between STUN and TURN.

Upvotes: 0

Alexan
Alexan

Reputation: 8637

You need to use STUN server for connect outside local network:

A STUN (Session Traversal of User Datagram Protocol [UDP] Through Network Address Translators [NATs]) server allows NAT clients (i.e. IP Phones behind a firewall) to setup phone calls to a VoIP provider hosted outside of the local network.

For example for Google STUN server:

var servers = { 'iceServers': [{ 'urls': 'stun:74.125.142.127:19302' }] };
//var  _iceServers = [{ url: 'stun:74.125.142.127:19302' }], // stun.l.google.com - Firefox does not support DNS names.

connection = new RTCPeerConnection(servers); 

You can look at my code.

And web application itself: https://signalrtc.com/

Upvotes: 6

Related Questions