场景:您想知道是否正在使用TURN服务器进行特定呼叫,以及是否正在使用您在创建PeerConnection期间提供的TURN服务器阵列中的哪一个。现在有两种选择:
我想使用上述两种方法的替代方法,以编程方式确定这一点,因此我不必离开我的应用程序页面。
答案 0 :(得分: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;
});
}
}
我想指出一点,所有这三种方法都在一个场景中失败:两个转向服务器在不同端口上从同一台机器运行,只有我发现的可靠方式是查看转弯服务器日志。
答案 1 :(得分:3)
更新:我已使用maplike getStats
更新了示例以遵循最新规范。
以下方法遵循the specification,目前仅适用于Firefox,因为Chrome目前不正确地实施getStats()
。希望很快就会有一个版本的adapter.js polyfill可以在Chrome中使用。
在Firefox中运行this fiddle时,您会看到:
checking
connected
Does not use TURN
这是因为该示例提供了STUN和TURN服务器。但是当我修改配置以仅使用iceTransportPolicy: "relay"
使用TURN时,我看到:
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);
&#13;
<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>
&#13;