FANCOMI Ad-Tech Blog

株式会社ファンコミュニケーションズ nend・新規事業のエンジニア・技術ブログ

WebRTCのさわりに

最初に

前回の投稿から早くも再投稿に選抜されてしまいましたtosh01です。

今回は、なぜか進展が気になっていたWebRTC (Web Real-Time Communication)に関して書かせていただきます。

WebRTCですが、Wikipediaには

WebRTC (Web Real-Time Communication)とはWorld Wide Web Consortium (W3C)が提唱するリアルタイムコミュニケーション用の(Javascript)APIの定義で、プラグイン無しでウェブブラウザ間のボイスチャットビデオチャット、ファイル共有ができる。

とありますが、簡単に言えばウェブブラウザ間でのP2Pによる双方向通信でWebSocketと違い、データ通信時にサーバを介さないクライアント端末間の相互接続を可能にする技術ということで、まだ対応ブラウザも少ないにも関わらず、今年に入ってからでしょうか?WebRTCを用いたサービスが次々と立ち上がってきていますので、またもや調査的な意味合い、開発するものとしての好奇心からWebRTCの技術の導入という観点で書かせていただきます。

概要

早速ですが、WebRTCではどのようにしてクライアント端末間での相互接続を可能にしているのでしょうか?

調査してみると、接続を実現するまでにはNATを越える為のSTUNやTURNなどのICE(Interactive Connectivity Establishment)サーバや接続情報を交換し合うシグナリングの為のサーバが必要とありますが、具体的には下記の情報をICEサーバや、シグナリングサーバを通し、ブラウザ同士で交換する必要があるようです。

  1. 接続先候補(candidate)
  2. オファーSDP(offer)
  3. アンサーSDP(answer)

※SDP Session Description Protocol(SDP)は通信のセッション名やセッションの有効時間などを扱うプロトコル

これらを使ってどのように実現しているのかは後述します。

いつごろだったでしょうか、はじめてWebRTCの技術の記事を見た時、興味を持ちAPIを読んでみようとしたのですが、さっぱり意味がわからずすぐに読むのをやめてしまった記憶があります。

今回、改めて、この技術を見ていくに当たり、現在ではこれらWebRTCのAPIを扱うWebRTC用のライブラリ(PeerJS,simpleWebRTC等)が公開されつつあるようですので、その中でも比較的情報が少なかったsimpleWebRTCを次に見てみたいと思います。

simpleWebRTC

simpleWebRTCですが、WebディベロッパーがWebRTCを使ったビデオチャットを下記のようなHTML5Javascriptのソースを書くだけで簡単にサイトに組み込めることができるライブラリになっています。

[html] <!DOCTYPE html> <html> <head> <script src="">http://simplewebrtc.com/latest.js"> </head> <body> <div id="localVideo" muted></div> <div id="remoteVideo"></div> <script> var webrtc = new SimpleWebRTC({ // 自身と相手のビデオ localVideoEl: 'localVideo', remoteVideosEl: 'remoteVideo', // オートでカメラリクエスト autoRequestMedia: true });

webrtc.on('readyToCall', function () {
    webrtc.joinRoom('Room name');
});
&lt;/script&gt;

</body> </html> [/html]

DEMOから確認もできるのですが、アドレスを共有し、ともにアドレスにアクセスすることにより、ビデオ画像を共有し、チャットができるようになっています。

もちろん色々拡張できるよう、ライブラリが各機能ごと10程度の独立したモジュールから成り立っており、望む仕様に合わせて利用、改修することができます。

ただし、接続情報を交換し合う為に必要なシグナリングサーバは開発・テスト用にのみ用意されているので、それ以外の目的で使うためには別途用意する必要があります。

次に、モジュールの一つRTCPeerConnectionはちょうどP2Pの接続を実現させるモジュールとなっていますのでこちらを少し見てみます。

RTCPeerConnection

1回の記事にWebRTCの技術全体を見て行くのは無理があると思いますので、一番核となる、STUN(ICE)サーバーを用い、NATの問題をクリアし、ブラウザ同士の双方向通信をどのようにして実現しているのかという部分を上記で紹介したsimpleWebRTCにおける<a href="https://github.com/HenrikJoreteg/RTCPeerConnection/blob/master/rtcpeerconnection.js" target="_blank">RTCPeerConnectionモジュールのJavascriptコードも眺めつつ、見て行きたいと思います。

まず双方向通信の足がかりとなるのがブラウザ間でのP2P接続を可能にするPeerConnection APIsでRTCPeerConnectionモジュール内で以下の接続の為のPeerConnection関数が定義されています。

そのPeerConnection関数内にて、下記のようにインスタンスが生成されます。 [javascript firstline="6"] this.pc = new webrtc.PeerConnection(config, constraints); // 引数configに、STUNサーバー情報など,constraintsには接続の種類により必要になる制約等が渡される WildEmitter.call(this); this.pc.onicecandidate = this._onIce.bind(this); // 自身の情報をSTUNサーバへ [/javascript]

接続のインスタンスが生成され、STUNサーバに自身の情報とともにアクセスするとSTUNサーバより接続候補(candidate)の情報が送信されます。

[javascript firstline="30"] PeerConnection.prototype._onIce = function (event) { // 自身の情報送信 if (event.candidate) { this.emit('ice', event.candidate); } else { this.emit('endOfCandidates'); } }; [/javascript] [javascript firstline="46"] PeerConnection.prototype.processIce = function (candidate) { // 接続候補受信 this.pc.addIceCandidate(new webrtc.IceCandidate(candidate)); }; [/javascript]

その後、自分の接続情報と接続要求のオファー(offer)を用意し、シグナリングサーバを介し接続先相手に送信します。

[javascript firstline="61"] this.pc.createOffer( // オファー(offer)送信 function (sessionDescription) { self.pc.setLocalDescription(sessionDescription); self.emit('offer', sessionDescription); if (callback) callback(null, sessionDescription); }, function (err) { self.emit('error', err); if (callback) callback(err); }, mediaConstraints ); [/javascript]

そして最後に、接続先相手がオファー(offer)を受信後、アンサー(answer)を作成し送信します。

[javascript firstline="99"] this.pc.setRemoteDescription(new webrtc.SessionDescription(offer)); // オファー(offer)情報を受け、アンサー(answer)作成 this.pc.createAnswer( function (sessionDescription) { self.pc.setLocalDescription(sessionDescription); self.emit('answer', sessionDescription); if (cb) cb(null, sessionDescription); }, function (err) { self.emit('error', err); if (cb) cb(err); }, constraints ); [/javascript]

そのアンサー(answer)を接続先相手から受信後、P2Pによる接続が出来るようになるという仕組みです。

[javascript firstline="127"] PeerConnection.prototype.handleAnswer = function (answer) { // アンサー(answer)を受信した時の処理 this.pc.setRemoteDescription(new webrtc.SessionDescription(answer)); }; [/javascript]

上記を経てようやく、サーバを介さないP2Pによる通信が実現します。

※詳しくはRTCPeerConnectionモジュールを参照して下さい。

最後に

WebRTCは今回扱わなかったファイル共有のAPI等まだまだ発展途上の技術ですが、Webディベロッパーにとっても、扱いやすい技術になっていくことが予想(期待)されるとともに、既存の技術やコンテンツと組み合わせたりすることにより、モバイルデバイスの普及も相俟って、Webの世界に影響を及ぼすサービスやコンテンツを生み出すポテンシャルを秘めていると思いますので、これからも進展が楽しみなところです。

WebRTCに関し、ある程度要約しつつ、一部分だけをピックアップして書かせていただきましたので、もっと詳細を知りたい方は参照をご覧下さい。

参照

simpleWebRTC simpleWebRTC - GitHub WebRTCで変わるWebの未来 - @IT Getting Started with WebRTC - HTML5 ROCKS TUTORIALS Web RTC WebRTC 1.0: Real-time Communication Between Browsers - W3C PeerJS WebRTC and the Early API - HACKS.MOZILLA.ORG