2015-08-21 31 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

相關問題