2015-08-21 34 views
5

场景:您想知道是否正在使用TURN服务器进行特定呼叫,以及您在创建PeerConnection时使用的TURN服务器阵列中的哪一个。现在有两种选择:WebRTC:确定在PeerConnection中使用哪个TURN服务器

  • Wireshark的:但是当你落后了公司代理服务器和TURN服务器之外的,Wireshark的将显示代理IP作为目标(也没有提运行它的不便之处。在背景中)
  • 通过统计页面去,并找出,铬 - >铬://的WebRTC,内部和Firefox - >约:的WebRTC

我想用一个替代上面两个,以编程方式确定这个,所以我不必离开我的应用程序页面。

+0

https://github.com/webrtc/apprtc/pull/99告诉您如何找出使用(UDP,TCP,TLS)TURN服务器的类型 - 它不不适用于Firefox,但这主要是apprtc示例稍微落后的问题。 –

回答

3

更新:我更新了示例以遵循最新的规范,使用maplikegetStats

以下方法跟在the specification之后,目前只能在Firefox中使用,因为Chrome目前不正确执行getStats()。希望adapter.js polyfill的一个版本即将推出,这也将使这项工作在Chrome中成功实现。

当您运行在Firefox this fiddle,你会看到:

checking 
connected 
Does not use TURN 

这是因为,例如同时提供了STUN和TURN服务器。但是,当我修改使用TURN的配置只能用iceTransportPolicy: "relay",我看到:

checking 
connected 
Uses TURN server: 10.252.73.50 

请注意,我用的是转服务器是后面的VPN,所以它不会为你工作,但随时修改摆弄你自己的服务器(只是不要保存它,除非你想让信息公开!)

虽然我没有测试多个回合服务器,但你可以看到显示的IP地址与回合服务器已配置,因此应该可以使用此方法来确定使用哪台服务器。

// 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>

+0

的错误,认为你总是需要提供一个mediatrack来接收统计信息,这要归功于清除它。 – mido

+0

对我来说问题是,有时某些端口在TURN服务器(在EC2实例上运行)中变得没有响应,所以我在多个端口上运行它们,所以虽然我们可以从rtc统计获得IP,但端口仍然是个谜 – mido

+0

@ mido22'candidate.portNumber'应该给你端口号。见[这里](http://w3c.github.io/webrtc-stats/#idl-def-RTCIceCandidateAttributes)。 – jib

3

我写了并测试了下面的一段代码,工作在两个Firefox和Chrome的最新版本,getConnectionDetails返回解析为连接细节一个承诺:

function getConnectionDetails(peerConnection){ 


    var connectionDetails = {}; // the final result object. 

    if(window.chrome){ // checking if chrome 

    var reqFields = [ 'googLocalAddress', 
         'googLocalCandidateType', 
         'googRemoteAddress', 
         'googRemoteCandidateType' 
        ]; 
    return new Promise(function(resolve, reject){ 
     peerConnection.getStats(function(stats){ 
     var filtered = stats.result().filter(function(e){return e.id.indexOf('Conn-audio')==0 && e.stat('googActiveConnection')=='true'})[0]; 
     if(!filtered) return reject('Something is wrong...'); 
     reqFields.forEach(function(e){connectionDetails[e.replace('goog', '')] = filtered.stat(e)}); 
     resolve(connectionDetails); 
     }); 
    }); 

    }else{ // assuming it is firefox 
    return peerConnection.getStats(null).then(function(stats){ 
     var selectedCandidatePair = stats[Object.keys(stats).filter(function(key){return stats[key].selected})[0]] 
      , localICE = stats[selectedCandidatePair.localCandidateId] 
      , remoteICE = stats[selectedCandidatePair.remoteCandidateId]; 
     connectionDetails.LocalAddress = [localICE.ipAddress, localICE.portNumber].join(':'); 
     connectionDetails.RemoteAddress = [remoteICE.ipAddress, remoteICE.portNumber].join(':'); 
     connectionDetails.LocalCandidateType = localICE.candidateType; 
     connectionDetails.RemoteCandidateType = remoteICE.candidateType; 
     return connectionDetails; 
    }); 

    } 
} 

我想指出一点,所有的这三种方法在一种情况下失败:两台服务器在不同端口上运行同一台计算机,只有可靠的方式才能看到服务器日志。

+0

感谢您的支持!我发现即使ICE连接状态“已完成”,结果中仍有大约25%的时间没有“Conn-audio”条目。任何想法为什么这可能是? –

+0

@RobAgar不知道是什么原因导致这个问题,试着问问jib或hancke,他们有更好的理解 – mido

相关问题