Reputation: 6556
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
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
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
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