STUN/TURN服务器连接测试

mir*_*our 33 stun webrtc turn

我试图弄清楚如何测试STUN/TURN服务器是否存活并正确响应连接.理想情况下,此测试将在外部机器上执行,以防万一STUN/TURN机器因此情况而停机,也应通过连接测试报告.

过去有没有人调查这个案子?建议采用什么解决方案?

mid*_*ido 33

编辑: github.io中一个很好的实现,从注释到另一个答案(在IceTransports值中选择"relay"):

Test TURN Server


按照Benjamin Trent的建议,我编写了以下代码来测试TURN服务器的连接,适用于firefox n chrome:

function checkTURNServer(turnConfig, timeout){ 

  return new Promise(function(resolve, reject){

    setTimeout(function(){
        if(promiseResolved) return;
        resolve(false);
        promiseResolved = true;
    }, timeout || 5000);

    var promiseResolved = false
      , myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection   //compatibility for firefox and chrome
      , pc = new myPeerConnection({iceServers:[turnConfig]})
      , noop = function(){};
    pc.createDataChannel("");    //create a bogus data channel
    pc.createOffer(function(sdp){
      if(sdp.sdp.indexOf('typ relay') > -1){ // sometimes sdp contains the ice candidates...
        promiseResolved = true;
        resolve(true);
      }
      pc.setLocalDescription(sdp, noop, noop);
    }, noop);    // create offer and set local description
    pc.onicecandidate = function(ice){  //listen for candidate events
      if(promiseResolved || !ice || !ice.candidate || !ice.candidate.candidate || !(ice.candidate.candidate.indexOf('typ relay')>-1))  return;
      promiseResolved = true;
      resolve(true);
    };
  });   
}
Run Code Online (Sandbox Code Playgroud)

示例用法:

checkTURNServer({
    url: 'turn:127.0.0.1',
    username: 'test',
    credential: 'test'
}).then(function(bool){
    console.log('is TURN server active? ', bool? 'yes':'no');
}).catch(console.error.bind(console));
Run Code Online (Sandbox Code Playgroud)

您可以运行以下代码段来检查:

var res = id('result');

id('button').onclick = function(){
	res.innerHTML = 'Checking TURN Server...';
  var url = 'turn:'+id('url').value+':'+id('port').value,
  		useUDP = id('udp').checked;
  url +='?transport=' + (useUDP ? 'udp': 'tcp');
  checkTURNServer({
      urls: url,
      username: id('name').value, 
      credential: id('pass').value
  }, id('time').value).then(function(bool){
  		if(bool)
         res.innerHTML = 'Yep, the TURN server works...';
      else
         throw new Error('Doesn\'t work');
  }).catch(function(e){
  	 console.log(e);
     res.innerHTML = 'TURN server does not work.';
  });
};


function checkTURNServer(turnConfig, timeout){ 
	console.log('turnConfig: ', turnConfig);
  return new Promise(function(resolve, reject){

    setTimeout(function(){
        if(promiseResolved) return;
        resolve(false);
        promiseResolved = true;
    }, timeout || 5000);

    var promiseResolved = false
      , myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection   //compatibility for firefox and chrome
      , pc = new myPeerConnection({iceServers:[turnConfig]})
      , noop = function(){};
    pc.createDataChannel("");    //create a bogus data channel
    pc.createOffer(function(sdp){
      if(sdp.sdp.indexOf('typ relay') > -1){ // sometimes sdp contains the ice candidates...
        promiseResolved = true;
        resolve(true);
      }
      pc.setLocalDescription(sdp, noop, noop);
    }, noop);    // create offer and set local description
    pc.onicecandidate = function(ice){  //listen for candidate events
      if(promiseResolved || !ice || !ice.candidate || !ice.candidate.candidate || !(ice.candidate.candidate.indexOf('typ relay')>-1))  return;
      promiseResolved = true;
      resolve(true);
    };
  });   
}


function id(val){
	return document.getElementById(val);
}
Run Code Online (Sandbox Code Playgroud)
#url{
  width: 250px;
}
#port{
  width: 70px;
}
Run Code Online (Sandbox Code Playgroud)
<h1>
 Test TURN server
</h1>
<div>
TURN URL: <input id='url' placeholder='example.com  or  xxx.yyy.rrr.ddd'  />
Port: <input type='number' value='3478' id='port' placeholder='enter a port number' />
</div>
<div>
Transport: <input type="radio" name="transport" id="tcp" value="tcp" /> TCP
<input type="radio" name="transport" id="udp" value="udp" checked/>UDP
</div>

<div>
Username: <input id="name" placeholder="turn username" />
</div>
<div>
password: <input id="pass" placeholder="turn password" />
</div>

<div>
checking Timeout: <input type='number'  id="time" placeholder="wait time  before checking timeout" value=5000 />
</div>
<div>
<button id='button'>
Check TURN Server
</button>
</div>

<h4 id='result'></h4>
Run Code Online (Sandbox Code Playgroud)

  • 什么应该是收集候选人的输出,以确保眩晕或转动服务器工作.https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ (3认同)
  • **不要将`test`用作用户名**,如示例所示.显然有一些`test`用户已经在浏览器的幕后实现,因此它被烧毁,如果你尝试它进行测试,事情就会失败,没有明显的原因.我发现没有关于这种行为的文档,但在使用不同的名称后,一切都突然开始起作用了...... (3认同)

Mor*_*itz 11

如果您对 coturn 服务器使用username:password身份验证机制,则较早的答案适用于 TURN 。然而,正如 BigBlueButton 和其他人static-auth-secret在 中看到的那样/etc/turnserver.conf,不可能使用https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

use-auth-secret
static-auth-secret=XXXX
Run Code Online (Sandbox Code Playgroud)

仍然测试TURN服务器的方法之一是安装turnutils_uclientsudo apt install coturn或者相应的包管理器。然后您可以随后使用(替换 XXXX 和 turn.example.com)对其进行测试:

turnutils_uclient -T -W XXXX turn.example.com
Run Code Online (Sandbox Code Playgroud)

这应该会产生以下输出(已编辑的 IP 地址 192.168.0.2 作为内部客户端地址和 1.2.3.4 作为服务器地址):

0: IPv4. Connected from: 192.168.0.2:50988
0: IPv4. Connected to: 1.2.3.4:3478
0: allocate sent
0: allocate response received: 
0: allocate sent
0: allocate response received: 
0: success
0: IPv4. Received relay addr: 1.2.3.4:56365
....
4: Total transmit time is 4
4: Total lost packets 0 (0.000000%), total send dropped 0 (0.000000%)
4: Average round trip delay 32.500000 ms; min = 15 ms, max = 56 ms
4: Average jitter 12.600000 ms; min = 0 ms, max = 41 ms
Run Code Online (Sandbox Code Playgroud)

在您的 TURN 服务器上,这应该在/var/log/coturn.log.

  • 还有用于 stun 的turnutils_stunclient:`turnutils_stunclient -p 3478 stunserver.com` (3认同)

gug*_*aiz 10

你可以在这里测试你的服务器......

https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

  • **此网址已过期**,请使用https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ (13认同)

小智 5

如果你想不断检查 stun 服务器,你可以使用 cron 执行此命令:

stunserver=stun1.l.google.com;stunport=19302;listenport=20000;echo -ne "\x00\x01\x00\x00YOGO\x59\x4f\x47\x4fSTACFLOW" | nc -u -p $listenport $stunserver $stunport -w 0;timeout 1 nc -l -u $listenport | head -c 32 | tail -c 4 | hexdump -e '/1 "%u" "."' | grep -o ".*[^.]" && echo yes-no-problem || mail -s "Error in Tun server:$stunserver:$stunport" root@localhost <<< 'Error in Tun server'
Run Code Online (Sandbox Code Playgroud)

将 root@localhost 替换为您的电子邮件以获取报告。

stunserver=stun1.l.google.com;
stunport=19302;
监听端口=20000;# 如果此端口不可用,请随意更改

将其添加到 cron 并每分钟执行一次。