Architectute
A webPage uses RTCPeerConnection to create a connection. It uses a STUN and a TURN server in its configuration. It creates an offer and sends the Offer to the remote client only after all the candidates have been gathered
if(pc.iceGatheringState === "complete"){
const resp = await fetch("REMOTE URL", {
method: "post",
body: JSON.stringify({
offer: btoa(JSON.stringify(pc.localDescription)),
}),
});
const sdp = await resp.text();
pc.setRemoteDescription(
new RTCSessionDescription(JSON.parse(atob(sdp)))
).catch((e) => console.log(e));
}
A remote (GO) server uses a REST API to accept the offer and respond with the answer. The answer is sent only after all the candidates have been gathered on the remote peer. I.e. after the "" candidate has been received
The remote server has a local RTP stream which is being sent to the host. The host adds a transceiver before it sends the offer
pc.addTransceiver("video", { direction: "recvonly" });
When an onTrack event is received, the stream is added to a variable and ONLY set as srcObject of the <video> component when the iceConnectionState changes to connected
Issue
The above setup works perfectly in case of a local network. Both, the host and the peer chose a host candidate and the video plays perfectly.
When using a remote connection, both, in case of a STUN (srflx) candidate and a TURN(relay) candidate, the video does not play.
chrome://webrtc-internals clearly shows the the Transport has chosen the right candidates but there is no traffic on the local candidate chosen.
I can see using the UDP dump on the remote peer that the video stream is being sent perfectly.
Debug Info
On remote network, using a srflex candidate, the nack and pli counts are very high compared to a local network
For approx 15 sec of video
pliCount:
local: 5
remote: 221
nackCount:
local: 7
remote: 2577
That sounds like packet loss to me. There are a few things that could be causing it.
Can you try lowering the bitrate of what you are sending? See if congestion is causing it.
Can you trying lowering the MTU? If you are forwarding packets from FFMPEG try appending pkt_size to the URL like this
Related
I was trying to save a SPA packet created via the fwknop-client on a client in client-server architecture.
The command that I have used is as follows
"fwknop -A tcp/22 -D server-ip --key-gen --use-hmac --save-packet --save-packet-file filename.pkt --save-rc-stanza -vv"
The command executes successfully but I'm not able to save the packet, the packet is not found in the system.
I also trying to append the packet using the "--save-packet-append" tag, but still not able to get the output.
The purpose for doing to above is to obtain the SPA packet and append the client certificate (asymmetric encryption) to this SPA packet which will be sent.
How can i save this packet to fulfil my purpose ?
Thank You
I just install Kamailio 4.4.5 + RTPEngine on Ubuntu Server 16.04
all config copy from https://github.com/whisk/WEBRTC-to-SIP
And using SIP.js latest version to make call between 2 chrome browser.
SIP user register successfully and can using text chat
But when User Invite another user any his Accept call, get this error
Failed to set remote answer sdp: Called with SDP without DTLS fingerprint.
How to solve this issue???
Use sdp_with_transport_like(...) instead of sdp_with_transport(...), because the transport string is UDP/TLS/RTP/SAVPF and the second function is doing an exact match, but the parameter in referred example is only RTP/SAVPF.
I'm developing a simple app that uses webrtc for transmitting real-time video in one direction (one sender and one receiver). It uses socket.io and node.js for the signalling.
At this moment, it's albe to transmit real-time video when the sender and receiver are in the same net (the server is already online), but if I use mobile net or if the peers are connected in different wifis it doesn´t work.
Actually, I make a test using public library's wifi and my home wifi and when the sender was in the public wifi it worked.
The message I get in firefox when it fails is :
ICE failed, see about:webrtc for more details
As I've read, webrtc uses STUN/TURN servers to solve problems with net's NATS. I have introduced urls from a STUN and a TURN server but it seems it had no effect.
This is the way I'm 'using' the STUN/TURN servers:
var configuration = { iceServers: [
{
urls: "turn:numb.viagenie.ca",
username: "xxxxxxxx#hotmail.com",
credential: "********"
},
{
urls: "stun:stun.callwithus.com"
}
]};
var pc = new RTCPeerConnection(configuration);
For both sides the same and it seems the servers are up.
So, my final question is, I need to do something else to make sure webrtc is using STUN/Turn servers when it's needed?
Or, do you know any other possible cause for this behaviour?
Everything you know can help a lot, because i couldn't find how to use those servers.
if you need more information, please ask for it.
T
Yes, you need to listen to pc.onicecandidate and send each candidate over your signaling channel to the other side, where you call pc.addIceCandidate with it like this, if using adapter.js:
pc.addIceCandidate(candidate).catch(e => console.log(e))
or like this if not (older syntax):
pc.addIceCandidate(new RTCIceCandidate(candidate)).catch(e => console.log(e))
You can also dump the ICE candidates to see if your settings work (srflx = stun, relay = turn):
var PC = window.RTCPeerConnection || window.webkitRTCPeerConnection;
var server = { urls: "stun:stun.l.google.com:19302" };
var pc = new PC({ iceServers: [server] });
pc.onicecandidate = e => e.candidate && console.log(e.candidate.candidate);
pc.createDataChannel("dummy");
pc.createOffer().then(d => pc.setLocalDescription(d)).catch(e => console.log(e));
You can modify that snippet to include your turn server.
console logs of failed comunication
That's an example of what I get in the console. It seems srflx and relay are used, but at some point I get a null candidate, the error on screenshot is because of i'm trying to log a 'candidate' property of a null object.
Finally, the problem was solved.
It seems that Turn server wasn't working fine. I made a trial account on xyrsis and changed the stun and turn servers and it was solved.
Thank you all.
For testing if I am getting the relay candidates, I am using this page: http://googlechrome.github.io/webrtc/samples/web/content/peerconnection/trickle-ice/. To test from chrome 40, I provided my turn url and credentials there. After clicking gather candidates I can see no relay candidates. Doing the same test from firefox 36, I found the relay candidates. What could be the possible problem ? To further investigate the issue, I looked into wireshark log. What I found is, from firefox the stun request format includes-
STUN 146 Allocate Request UDP lifetime: 3600 user: lazy realm: with nonce
But from chrome, this is slightly different-
STUN 70 Allocate Request UDP
It seems the request code is not same. Moreover, request from chrome doesn't include the lifetime, user and realm property.
I know the question is already a bit old, however from my experience the TURN server description format (with regards to authentication) has to be formatted differently in Chrome and Firefox.
For chrome you can use:{"url": "turn:user#turn.example.com", credential:"password"},
For Firefox the format is:
{"url": "turn:turn.example.com", 'hasCredentials': true, username:"user", credential:"password"},
Maybe you can check the source to see how the turn servers are set in the example.
Edit:
Meanwhilst the format of the servers list has changed in the specification (https://www.w3.org/TR/webrtc/#rtciceserver-dictionary). Currently all implementations i know support the format:
{ "urls": ["turns:turn.example.org", "turn:turn.example.net"],
"username": "user",
"credential": "myPassword",
"credentialType": "password"
}
On Edge however it seems you need to include the query string ?transport=udp in the url.
I am trying to setup a peer to peer connection for WebRTC application. I have read the forums and discussion groups which lead me to the point that STUN/TURN servers are required for the same. Here are the details:
I downloaded the open source implementation of the STUN/TURN server from https://code.google.com/p/rfc5766-turn-server/
Installed the server on my local Mac OS X machine and turned on the server on localhost:3478
When I tested the server using the client scripts, I was able to get back the remote address from the server.
However, when I try to hit the server from my JavaScript code while creating a peer to peer connection, it is not hitting the server itself.
Below is the code which I am using :
function createPeerConnection() {
var pc_config = {'iceServers': [{'url':'turn:127.0.0.1:3478', 'credential':'Apple123'}]};
try {
// Create an RTCPeerConnection via the polyfill (adapter.js).
pc = new webkitRTCPeerConnection(pc_config);
pc.onicecandidate = gotLocalCandidate;
trace("Created RTCPeerConnnection with config:\n" + " \"" +JSON.stringify(pc_config) + "\".");
} catch (e) {
trace("Failed to create PeerConnection, exception: " + e.message);
alert("Cannot create RTCPeerConnection object; WebRTC is not supported by this browser.");
return;
}
pc.onconnecting = onSessionConnecting;
pc.onopen = onSessionOpened;
pc.onaddstream = onRemoteStreamAdded;
pc.onremovestream = onRemoteStreamRemoved;
}
Appreciate any guidance in this matter as I am completely stuck at this point.
One more question: How to setup a peer to peer connection for WebRTC application where both peer A and B are present on an internal network? Is STUN/TURN servers required then?
First, TURN servers are something that are used only if failing to setup an p2p connection directly. About 86% of all calls can be made without relaying via a TURN server (according to this slide, which I by the way recomend to get a better understanding of TURN (from slide 44)).
TURN server should be outside your network since the purpose of it is to relay the stream when not possible to do so in other way.
I would recomend you to start with the case where both A and B are on the same network. Then you do not need to worry about using STUN/TURN. It's enough complicated as it is.