web-dev-qa-db-ja.com

WebRTCにシグナリングサーバーが必要なのはなぜですか?

WebRTCは、ピアツーピア間のメディアデータの転送方法を定義するプロトコルです。わかった。また、RTP/UDPの上で動作します。これも分かりました。

シグナリングサーバーについての議論をしている間、それは互換性チェック/チャネルの開始を行う必要があると述べられています...などが機能します。

私の質問は:上記で述べたこと

1)シグナリングサーバーが必須であることを意味しますか?

2)WebRTCには、シグナリングサーバーなしで他のピアと直接通信するインテリジェンスはありませんか?

3)WebRTCに関連するすべての記事は、「ブラウザ間通信の間ですか?」という文で始まります。つまり、WebRTCは、a)カメラ付き組み込みデバイス[ブラウザなし]、b)他の場所のブラウザ間では使用できません。

4)また、ブラウザにストリーミングする従来の方法と比較して、WebRTCを使用するとどのような利点がありますか? [正直なところ、従来の方法がわかりません]。

私はそれが理論的な問題であることを知っています。しかし、私はこの種の質問がおそらくインターネットのさまざまなコンテキストに浮かんでいるのを見ます。この質問がいくつかのアーキテクチャレベルの答えを与えることを願っています。ありがとう。

31
Whoami

WebRTCはディスカバリーを解決しません(またはそれを解決しません)。

WebRTCは、シグナリングサーバーなしで別のピアと直接通信する方法を認識していますが、別のピアを発見する方法を認識していません。発見は本質的な問題なので、WebRTCがそれを解決してくれると人々が期待するのは少し困惑しています。

それについて考えてください:どのように私に電話するのですか? 10億人ではなく、私との連絡を開始するようにコンピューターをどのように指示しますか? GPS座標で?電子メールアドレス?固定IP? irc?インスタント・メッセージ?フェイスブック?電話番号?

また、あなたが電話したとき、どうすればわかりますか?私のコンピュータは「鳴る」でしょうか?通常のWebテクノロジーでこれを解決するには数百の方法があるので、WebRTCが特定の方法を指示した場合は、害を及ぼします。アプリケーションのコンテキストは、おそらく連絡の最良の手段を通知します。たぶん、オンラインフォーラムやオンラインゲームのバーチャルルームであなたに会いますか?

技術的に言えば、ピアにSDPオファー(テキストの一部)を取得する他の手段がある限り、厳密にWebRTCを備えたシグナリングサーバーは必要ありません。電話テキスト、IM、irc、電子メール、または通信会社の鳩によって、相互のSDP回答を受け取ります。これをChromeまたはFirefox: https://jsfiddle.net/nnc13tw2 で試してください-「オファー」をクリックして(最大20秒待機)、出力をそれを最後の同じフィールドに貼り付けてEnterキーを押し、回答を送り返してもらう友人。これをAnswerフィールドに貼り付けてEnterキーを押します。これで接続され、接続サーバーは関与しなくなりました。

Jsfiddleが機能する理由:これは、SDP内のすべてのICE候補をパッケージ化します。これには数秒かかることがあり、一度に必要なすべてを提供します。

通話中にビデオソースの数を変更するなど、一部の高度な機能でもシグナリングが必要ですが、通話が確立されると、アプリは独自のデータチャネルを使用して、ピア間のさらなるシグナリングニーズに対応できます。

Stackoverflowはjsfiddleにリンクするコードを含めることを要求するので、ここにも含める必要があります(ただし、Chromeを使用している場合は、カメラへのアクセスができないため、スニペットで動作するようです):

var config = { iceServers: [{ urls: "stun:stun.l.google.com:19302" }]};

var dc, pc = new RTCPeerConnection(config);
pc.onaddstream = e => v2.srcObject = e.stream;
pc.ondatachannel = e => dcInit(dc = e.channel);
v2.onloadedmetadata = e => log("Connected!");

var haveGum = navigator.mediaDevices.getUserMedia({video:true, audio:true})
  .then(stream => pc.addStream(v1.srcObject = stream))
  .catch(failed);

function dcInit() {
  dc.onopen = () => log("Chat!");
  dc.onmessage = e => log(e.data);
}

function createOffer() {
  button.disabled = true;
  dcInit(dc = pc.createDataChannel("chat"));
  haveGum.then(() => pc.createOffer()).then(d => pc.setLocalDescription(d)).catch(failed);
  pc.onicecandidate = e => {
    if (e.candidate) return;
    offer.value = pc.localDescription.sdp;
    offer.select();
    answer.placeholder = "Paste answer here";
  };
};

offer.onkeypress = e => {
  if (!enterPressed(e) || pc.signalingState != "stable") return;
  button.disabled = offer.disabled = true;
  var desc = new RTCSessionDescription({ type:"offer", sdp:offer.value });
  pc.setRemoteDescription(desc)
    .then(() => pc.createAnswer()).then(d => pc.setLocalDescription(d))
    .catch(failed);
  pc.onicecandidate = e => {
    if (e.candidate) return;
    answer.focus();
    answer.value = pc.localDescription.sdp;
    answer.select();
  };
};

answer.onkeypress = e => {
  if (!enterPressed(e) || pc.signalingState != "have-local-offer") return;
  answer.disabled = true;
  var desc = new RTCSessionDescription({ type:"answer", sdp:answer.value });
  pc.setRemoteDescription(desc).catch(failed);
};

chat.onkeypress = e => {
  if (!enterPressed(e)) return;
  dc.send(chat.value);
  log(chat.value);
  chat.value = "";
};

var enterPressed = e => e.keyCode == 13;
var log = msg => div.innerHTML += "<p>" + msg + "</p>";
var failed = e => log(e);
<video id="v1" height="120" width="160" autoplay muted></video>
<video id="v2" height="120" width="160" autoplay></video><br>
<button id="button" onclick="createOffer()">Offer:</button>
<textarea id="offer" placeholder="Paste offer here"></textarea><br>
Answer: <textarea id="answer"></textarea><br><div id="div"></div>
Chat: <input id="chat"></input><br>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
43
jib
  1. はい、シグナリングは必須です。これにより、ICE候補などが交換され、ピア接続がそのピアが誰であるかを認識します。
  2. いいえ、なんらかのやり取りなしでピアをどのようにして知るのでしょうか。
  3. いいえ、そうではありません。 raspis、およびWebRTCピア接続を介してブラウザーページにビデオをストリーミングする他のネイティブデバイスを使用して、数多くの実験を行いました。
  4. あなたは何について話していますか? WebRTC対Flashおよび中央サーバーを使用する利点を意味しますか? WebRTCはピアツーピアであり、それをGetUserMediaおよびHtml5と組み合わせると、すべてのメディア交換を処理するためのフラッシュおよび中央メディアサーバーの必要性がなくなります。
8
Benjamin Trent

2つの任意のピア間の接続を確立できるようにするには、シグナリングサーバーが必要です。これは、今日使用されているインターネットアーキテクチャの単純な現実です。

Web上の別のピアに連絡するには、まずそのIPアドレスを知る必要があります。すでに最初の問題があります。ピアのIPアドレスを知る必要があります。これらのコンピューターの前に座っている人たちが電話でお互いに電話をかけたり、IPアドレスを指示したりせずに、この情報をピアAからピアBにどのように取得しますか?これを行うには、各ピアが最初に独自のアドレスを検出してから、それを他のピアに送信します。これにより、さらに2つの問題が発生します。ピアはどのようにして外側に面したIPアドレス(自分のIPとは大幅に異なる可能性がある)を発見し、これをまだ不明なアドレスの他のピアにどのように通信しますか?

これがシグナリングサーバーの出番です。両方のピアは、相互に接続する前に、シグナリングサーバーに接続しています。そのため、彼らは直接通信する方法を交渉するまで、彼らに代わってメッセージを中継するためにシグナリングサーバーを使います。ローカルサブネット上でサードパーティの支援なしに接続をネゴシエートすることは可能です。しかし、このシナリオはおそらく非常にまれで、仕様がそれを扱っているかどうかさえわかりません。

3)と同様に、WebRTCは任意のデバイスに実装できます。これは単なるプロトコルです。ブラウザだけに限定されているわけではありません。

4)に関しては、あるブラウザーから別のブラウザーに何かをストリーミングする「レガシー」方法では、常に中間に中継サーバーが含まれていました。このサーバーには大きなCPUと帯域幅の要件があり、高価なボトルネックです。 WebRTCは、軽量のシグナリングサーバーを除いて、仲介者なしで直接P2P接続を可能にします。また、実際にはオープンスタンダードはありませんでした。ほとんどの場合、何らかの方法でアドビにお金を支払うことになります。

6
deceze

答えのほとんどはカバーされていますが、少しだけ追加すると思います。 Googleが最初にwebRTCを作成し、それを4年前にオープンソース化したとき、それはシグナリング機能なしで、それだけで独自に厳密に行われました。

しかし、最近GoogleがFirebaseを購入したので、WebRTCの完全なエンドツーエンドソリューションを調達して間もなくオープンになり、私たち全員がより簡単に実装できるようになると思います。

Firebaseと言えば、私は試してみましたが、悪くはありません。基本的な作業は完了しました: http://antonvolt.com/prototype2/

0
AntonV