web-dev-qa-db-ja.com

STUN / TURNサーバー接続テスト

STUN/TURNサーバーが生きていて、接続に適切に応答しているかどうかをテストする方法を見つけようとしています。理想的には、このテストは外部マシンから実行されます。この場合、STUN/TURNマシンがダウンしている場合に備えて、接続テストでも報告する必要があります。

過去にこのケースを調べた人はいますか?どのソリューションが推奨されますか?

31
mirazour

編集:github.ioでのコメントから別の回答への素敵な実装(IceTransports値で「リレー」を選択):

Test TURN Server


benjamin Trentのアドバイスに従って、次のコードを作成してTURNサーバーの接続性をテストし、firefoxと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);
    };
  });   
}

使用例:

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));

以下のスニペットを実行して確認できます。

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);
}
#url{
  width: 250px;
}
#port{
  width: 70px;
}
<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>
32
mido

ここでサーバーをテストできます...

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

9
gugaiz

TURNおよびSTUNサーバーをテストします こちら

4
Devaroop

サードパーティの監視サービス(Monitisを使用)または独自のマシンをセットアップして、[〜#〜] ping [〜#〜]毎分1つ以上の場所からサーバーを設定できます。ただし、これは、サーバーがreachableであるかどうかのみを示し、TURN/STUNアプリケーションサーバーがまだ受け入れて応答するかどうかを示すものではありません。 TURN/STUNパケットへ。

STUN/TURNのサーバー側監視ライブラリは、素晴らしいGitHubプロジェクトになります。

0
Octavian Naicu

100,000人の仮想ユーザーや100万人の仮想ユーザーなどのターンサーバーの高負荷テスト用の商用ツールを使用している場合は、Load Multiplierツール(www.loadmultiplier.com)を確認できます。また、coturnサーバーをテストする特定のページについても説明します here

Load Multiplierツールは、ダミーの信号プレーンをシミュレートすることに注意してください(クライアント間でSDPを交換するため)。また、SRTP/DTLSメディアを使用して、STUN、TURN、およびICEをテストできます。

0
Austin

TURNとSTUNサーバーの両方をチェックする@mido関数のバージョン(元はstunサーバーを拒否):

function checkTurnOrStun(turnConfig, timeout){ 
  return new Promise(function(resolve, reject){

    setTimeout(function(){
        if(promiseResolved){
            if (promiseResolved == 'STUN') resolve('STUN');
            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 = 'TURN'; 
        resolve(true);
      }
      pc.setLocalDescription(sdp, noop, noop);
    }, noop);    // create offer and set local description
    pc.onicecandidate = function(ice){  //listen for candidate events
      if( !ice || !ice.candidate || !ice.candidate.candidate)  return;
      if (ice.candidate.candidate.indexOf('typ relay')!=-1) { promiseResolved = 'TURN'; resolve('TURN'); }
      else if (!promiseResolved && (ice.candidate.candidate.indexOf('typ Host')!=-1 || ice.candidate.candidate.indexOf('typ srflx')!=-1)){
          promiseResolved = 'STUN';
        if (turnConfig.url.indexOf('turn:')!==0) resolve('STUN');
      }
      else return;
    };
  });   
}

checkTurnOrStun({"url": "stun:stunserver.org"}).then(function(result){
    console.log(
    result ? 'YES, Server active as '+result : 'NO, server not active');
}).catch(console.error.bind(console));

checkTurnOrStun({
            url: 'turn:numb.viagenie.ca',
            credential: 'muazkh',
            username: '[email protected]'
}).then(function(result){
    console.log(
    result ? 'YES, Server active as '+result : 'NO, server not active');
}).catch(console.error.bind(console));
0