スキップしてメイン コンテンツに移動

投稿

3月, 2014の投稿を表示しています

P2P探訪 WebRTC用、SDP交換Peerを作ってみた。〜WebRTCで転送する〜

続きです。
WebRTCのPeerに、SDPデータを転送する機能を追加してみました。


WebRTCを用いてP2P通信を確立するには、SDPを交換する必要があるのでした。SDPの交換はWebRTCフレームワークで提供されていないので、自作する必要があったのでした。

今回は、WebRTCのPeerにSDPデータを交換する機能を実現してみました。
本機能によって、一度ネットワークに参加する事が出来たならば、サーバーを経由せずに、P2Pネットワークを成長させる事ができるようになります。


[仕組み] WebSocketの場合とほとんど同じです。通信方法がWebSocketから、WebRTCのデータコネクションに変わるだけです。
仲介役のPeerが指定されたアドレス(uuid)のPeetへメッセージを送信する機能を実現するだけで良いでしょう。

例えば、以下のような感じで書けます。

function MessageTransferBase(target) { this.mParent = target; // 他のPeerからメッセージを受け取った MessageTransferBase.prototype.onReceiveMessage = function(caller,message) { }; //仲介者(transfer)を経由して、メッセージを送信してもらう。 MessageTransferBase.prototype._sendUnicastMessage = function(transfer, to, from, content) { console.log("======sendUnicastMessage :"); var mes = {}; mes.messageType = "unicast"; mes.to = to; mes.from = from; mes.content = content; this.mParent.getPeerList().get(transfer).caller.sendMessage(JSON.stringify(mes)); } //仲介の依頼ならば、仲介してあげる。自分へのメッセージならば、…

P2P探訪 WebRTC用、SDP交換サーバーを作ってみた。〜WebSocketで転送する〜

続きです。
WebSocketを用いて、SDPデータを転送する機能を実現しました。


[コネクションを維持して任意のタイミングで通信] 通常、ブラウザーでサイトにアクセスする場合、ブラウザーは必要なデータをダウンロードすると、コネクションを切ります。

コネクションが切れてしまうと、サーバーからクライアントへメッセージを送信する事ができません。
なので、以前は、ホームページの表示完了後、少し時間がたってからサーバーから何かしらのPush通信を受けると行った事が出来ませんでした。

しかし、WebSocketが誕生しこの状況はいっぺんします。
WebSocketを使った場合、サーバーとクライアントのコネクションはクローズされず、維持し続けます。これによって、サーバーから、クライアントへメッセージを送信する事ができるようになりました。

WebSocketを使えば、任意のタイミングで、サーバーとブラウザーが通信できます。
この機能を利用すれば、容易にSDP交換サーバーの実現することができるでしょう。

[SDP交換サーバーの役目]
SDP交換サーバーの役目は、(a)Peerの存在を他のPeerへ伝える事。そして、(b)SDP情報を、Peer同士で交換できるようにする事です。

今回作成した、SDP交換サーバーでは、以下の機能を実装しました。
[1]  Peer全体にメッセージを送信する。
[2] 指定したUUIDのPeerへメッセージを送信する。


あたらに加わったPeerが、「[1]の機能」を用いて、p2pネットワーク全体にUUIDを送信すれば、「(a)の目的」を果たす事ができます。
また、P2P接続を確立したい場合、「[2]の機能」を用いて、他のPeerへ自身のSDPを送る事ができるでしょう。


[実装] nodejsを使って実現しました。
https://github.com/kyorohiro/HelloWebRTC/blob/master/signalServer/signalserver.njs

// httpサーバーを立ち上げる this.mHttpServer = HTTP.createServer(function (req, res) { ... } // websocketサーバーを立ち上げる this.…

P2P探訪 WebRTC用、SDP交換サーバーを作ってみた。〜 UUIDでPeerを識別する 〜

WebRTCを用いて、P2P通信をする場合には、SDPというデータを交換する必要がある事を説明しました。
ただし、このSDPを交換する部分はWebRTCでは提供されていません。自作する必要があるでしょう。※有り物を拝借するでも良いです。

試しに、WebSocketを使ってSignalServer(SDP交換機)を作成してみました。紹介します。


[UUIDでPeerを識別する] 多数のPeerの交換器としてサーバーを動作させたい場合、各Peerを識別する方法が必要です。
特にP2Pシステムでは、統制を取らずに一意の識別子の作成をする事が望ましいです。
※今は交換サーバーが一つを想定しているので、本来考慮する事ないかもしれません。

今回は乱数を使用して実現しました。128bitの値を乱数で生成します。0〜2**128の値衝突する確率は、1/2**64ととても少ないのです。
※ アレと思った方は、「誕生日攻撃」ググると良い
// ref http://note19.com/2007/05/27/javascript-guid-generator/ function s4() { return (((1+Math.random())*0x10000)|0).toString(16).substring(1); } function createUUID() { return s4()+s4()+"-"+s4()+"-"+s4()+"-"+s4()+"-"+s4()+s4()+s4(); } ※rfc4122では、最初の6bitは予約されています。


[次回] 続きを書く..。その続きは、Peerに交換機の機能を付けたサンプルを紹介する予定。

※ 成果物は以下
https://github.com/kyorohiro/HelloWebRTC/tree/master/signalServer





P2P探訪 StunでNat越え その7 WebRTCでShakehand

前回、Stunの実例として、WebRTCを利用してSDP(自身のアドレスとポート)を取得しました。せっかくなので、WebRTCを使って、Peer同士でメッセージのやり取してみましょう。


WebRTCを用いて、お互いのPeerが接続してメッセージを送る方法は簡単です。
1. 自分のSDPと相手のSDPを取得する。
2. 取得したSDPを設定する。
3. メッセージを送信する。※今回はテキスト

とするだけです。

[解説] 以前説明した通り、Peerどうしが接続するためには、接続相手のアドレスを知る必要があります。このアドレスを知りたい場合には、Stunサーバーを利用するのでした。

また、接続される側も、接続してくるPeerのアドレスがわかっていれば、「UDPパンチ」などを用いて、接続できる可能性をあげる事ができるのは、ご存知のことでしょう。以前解説したとおりです。

WebRTCも同様の手法を取っています。「接続される側」、「接続する側」のアドレスを前もって、WebRTCの知らせる事で、Peer同士が接続できるようになります。

※注意点
WebRTCでは、「接続される側」、「接続する側」のアドレスを、Peerに知らせる方法は提供されていません。
独自に実装する必要があります。WebSocketを利用する方法流行っているみたいです!!



[接続の処理の流れ] 実際の処理の流れを見てみましょう。接続が完了すれば、メッセージを送信できるようになります。

○自分のSDPを取得/設定
#接続を要求する側
O-1. RTCPeerConnectionを生成する。
O-2. RTCPeerConnection#createOffer()をコールする。
O-3. RTCPeerConnection#setLocalDescription()をコールして設定する
#接続を受け入れる側
A-1. RTCPeerConnectionを生成する
A-2. RTCPeerConnection#createAnswer()をコールする
A-3. RTCPeerConnection#setLocalDescription()をコールして設定する ※A-2の操作は先に接続要求してきている、SDPを設定しておく必要があります
○相手のSDPを設定する #接続を要求する側/#接続を受け入れる側
A/O-1.…