Aktualizacja: Zaktualizowałem przykład, aby śledzić najnowszą specyfikację, z maplikegetStats
.
Następujące podejście jest zgodne z the specification i obecnie działa tylko w przeglądarce Firefox, ponieważ Chrome w tej chwili nieprawidłowo implementuje getStats()
. Mamy nadzieję, że wkrótce pojawi się wersja polyfillu adapter.js, która sprawi, że będzie działać również w Chrome.
Po uruchomieniu this fiddle w Firefoksie, zobaczysz:
checking
connected
Does not use TURN
To dlatego, że przykładem zapewnia zarówno STUN i serwer TURN. Ale kiedy modyfikować config do korzystania tylko z iceTransportPolicy: "relay"
TURN widzę:
checking
connected
Uses TURN server: 10.252.73.50
Należy pamiętać, że serwer kolej używam jest za VPN, więc nie będzie pracować dla Ciebie, ale czuć się swobodnie modyfikować skrzypiec z własnym serwerem (po prostu nie zapisuj go, chyba że chcesz, aby informacje stały się publicznie dostępne).
Chociaż nie testowałem więcej niż z jednym serwerem, jak widać, wyświetlony adres IP odpowiada skrętowi skonfigurowany serwer, więc powinno być możliwe określenie, który serwer jest używany przy użyciu tego podejścia.
// Turn server is on Mozilla's VPN.
var cfg = { iceTransportPolicy: "all", // set to "relay" to force TURN.
iceServers: [{ urls: "stun:stun.l.google.com:19302" },
{ urls: "turn:10.252.73.50",
username:"webrtc", credential:"firefox" }] };
var pc1 = new RTCPeerConnection(cfg), pc2 = new RTCPeerConnection(cfg);
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
pc2.oniceconnectionstatechange =() => log(pc2.iceConnectionState);
pc2.onaddstream = e => v2.srcObject = e.stream;
var findSelected = stats =>
[...stats.values()].find(s => s.type == "candidate-pair" && s.selected);
var start =() => navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => pc1.addStream(v1.srcObject = stream))
.then(() => pc1.createOffer()).then(d => pc1.setLocalDescription(d))
.then(() => pc2.setRemoteDescription(pc1.localDescription))
.then(() => pc2.createAnswer()).then(d => pc2.setLocalDescription(d))
.then(() => pc1.setRemoteDescription(pc2.localDescription))
.then(() => waitUntil(() => pc1.getStats().then(s => findSelected(s))))
.then(() => pc1.getStats())
.then(stats => {
var candidate = stats.get(findSelected(stats).localCandidateId);
if (candidate.candidateType == "relayed") {
log("Uses TURN server: " + candidate.ipAddress);
} else {
log("Does not use TURN (uses " + candidate.candidateType + ").");
}
})
.catch(log);
var waitUntil = f => Promise.resolve(f())
.then(done => done || wait(200).then(() => waitUntil(f)));
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var log = msg => div.innerHTML += msg +"<br>";
var failed = e => log(e +", line "+ e.lineNumber);
<video id="v1" width="108" height="81" autoplay></video>
<video id="v2" width="108" height="81" autoplay></video><br>
<button onclick="start()">Start!</button><br><div id="div"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
https://github.com/webrtc/apprtc/pull/99 pokazuje, w jaki sposób dowiedzieć się, rodzaj używanego serwera TURN (UDP, TCP, TLS) - to robi Działa w Firefoksie, ale jest to głównie kwestia, że próbka apprtc jest nieco w tyle. –