2015年7月16日木曜日

P2P探訪 P2Pファイル共有アプリ。 HetimaTorrentClient (pre-Alpha) ver 0.0.3 をリリースしました。

P2Pファイル共有アプリ。 HetimaTorrentClient (pre-Alpha) ver 0.0.3 をリリースしました。
https://chrome.google.com/webstore/detail/hetimatorrentclientpre-al/bepllifcfhpjoijdddiafgmclfhgjnfb

Dart製の Chrome App です。まだまだ不安定。今回は、Torrent ライブラリの部分も、Dartlang を用いて、フルスクラッチで書きました。 興味のある型は以下をご確認くだい。 ( https://github.com/kyorohiro/dart_hetimatorrent )
BEP 0003 ( http://www.bittorrent.org/beps/bep_0003.html) に準拠しています。もちろん、pre-Alpha版なので、まだまだ安定していません。安定版はもう少々お待ち下さい。

 

 
 
 
 

[PS]

- HetimaTorrentTracker とセットで利用してください

Torrent Clientは、データを配信する際に、Trackerサーバーが必要になります。hetima torrent library では、このサーバーアプリも用意しています。 名前をHetimaTorrentTrackerと言います。こちらも、Chrome Appです。



- ノウハウは「なぜなにトレント」を参照してください

Torrent Clientを作成した時の発見したことをチュートリアル形式で、ドキュメント化しています。P2Pアプリの作成について興味のある方はこちらも御覧ください。
(※ 書きかけです。)
当面は、gitbook版の方で更新していきますが、整形したものをpaboo版にも展開する予定です。









2014年7月20日日曜日

[メモ] DartをCentOSにインストールする

DartをCentOS release 6.4 (Final)なんかで使おうとすると、「GLIBC_2.15' not found」と表示されて上手く動作しないことがある。

なので、自前でビルドする必要がある。
例えば、version1.5のdartを利用した場合は、以下のような感じで環境を作る事ができる。

[How to build/install dart sdk in centos 2014/07/20]
  [create env]
   sudo yum -y install subversion
   sudo yum -y install make
   sudo yum -y install gcc-c++
   sudo yum -y install java-1.6.0-openjdk-devel
   gclient config http://dart.googlecode.com/svn/branches/1.5/deps/all.deps
   gclient sync
   gclient runhooks
  [build]
   cd dart
   tools/build.py --mode=release --arch=x64 create_sdk
  [ref]
   https://code.google.com/p/dart/wiki/BuildingOnCentOS

上手くビルドできたら、 dart/out/ReleaseX64/dart-sdk/bin は以下にパスを通してあげればOK。

パッケージをアップデートしたい時
   pub get
   pub upgrade

実行したい時
dart xxx.dart

といった感じで、コマンドから操作できます。



2014年3月22日土曜日

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));
 }
        //仲介の依頼ならば、仲介してあげる。自分へのメッセージならば、受信する。
 MessageTransferBase.prototype.onTransferMessage = function(caller, message) {
     var p2pMes = JSON.parse(message);

      if("unicast" == p2pMes.messageType) {
       console.log("======onTransferMessage:");
       var mes = {};
       mes.to = p2pMes.to;
       mes.from = p2pMes.from;
       mes.content = p2pMes.content;
       mes.messageType = "transfer";
       var targetPeer = this.mParent.getPeerList().get(p2pMes.to).caller;
       targetPeer.sendMessage(JSON.stringify(mes));
      }
      else if("transfer" == p2pMes.messageType) {
       this.onReceiveMessage(caller, p2pMes);
      }
 }
}


https://github.com/kyorohiro/HelloWebRTC/blob/master/signalPeer/peer/messagetransferbase.js

[次回予告]

成果報告っぼくなってきているので、「今までの成果をノウハウとしてまとめる」。
数百〜数千のPeerがネットワーク上で、自己組織的にネットワークを構築して、データやPeerを検索する仕組の構築方法」。「Torrentベースの高速データ配信の導入」のどれか

2014年3月12日水曜日

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.mWsserverSocket = new WSServer({httpServer: this.mHttpServer});
    this.mWsserverSocket.on('request', function(req){
          ....
          ....
       // 受け取ったメッセージを解析して、転送する。  
       if(messageType === "unicast") {
       var v = {}
            v["_contentType"]    = contentType;
            v["_content"] = content;
            v["_to"]      = to;
            v["_from"]    = from;
           //[1] Peer全体にメッセージを送信する。
            _own.uniMessage(to, JSON.stringify(v));
       } else if(messageType =="broadcast") {
             var v = {}
             v["_contentType"] = contentType;
             v["_content"]     = content;
             v["_from"]        = from;
             //[2] 指定したUUIDのPeerへメッセージを送信する。
             _own.broadcastMessage(JSON.stringify(v));
       } 
    });


[次回]

続きを書きます。クライアント側の解説をもう少しします。それが終わったら、各Peerにもこの機能を持せたサンプルを提供します。
余裕があれば、それを土台に主だったDHTを、WebRTC上で実現できるか検証してみます。




2014年3月11日火曜日

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






2014年3月1日土曜日

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. RTCPeerConnection#setRemoteDescription()をコールする。

[サンプルコード]

○サンプルコード

WebRTCを利用して、テキストを送る事ができます。
※通常は、SDPデータを交換するのに、WebSocketを使います。しかし、今回のサンプルでは、WebSocket用のサーバーを用意する必要はありません。その部分は手動で行うように作りました。


[次回]

....次回は、WebRTCを使って、何かします。たぶん、Torrentの考え方を応用したサンプルを紹介します。




2014年2月25日火曜日

P2P探訪 StunでNat越え その6 WebRTCでSDPを取得

P2Pの起爆剤になりそうなものとして、もっとも有力なのは、WebRTCではないでしょうか。
WebRTCを用いれば、ブラウザーで、P2Pアプリの機能を提供することができます。

もちろん、WebRTCではSTUNサーバーが利用されています。
さっそく、STUNを介して、自身のアドレスを取得してみましょう。


1. RTCPeerConnection を生成する。
2. RTCPeerConnection#createOffer()をコールする

でOKです。

以下のような値を取得できます。SDPと呼ばれています。

...
...
m=audio 55491 RTP/SAVPF 111 103 104 0 8 106 105 13 126
c=IN IP4 111.100.57.xxx
a=rtcp:55491 IN IP4 111.100.57.214
a=candidate:38022971xx 1 udp 21139371xx 192.168.0.3 55491 typ host generation 0
a=candidate:38022971xx 2 udp 21139371xx 192.168.0.3 55491 typ host generation 0
a=candidate:12749365xx 1 udp 18455016xx 111.100.57.2xx 55491 typ srflx raddr 192.168.0.3 rport 55491 generation 0
a=candidate:12749365xx 2 udp 18455016xx 111.100.57.2xx 55491 typ srflx raddr 192.168.0.3 rport 55491 generation 0
a=candidate:28878806xx 1 tcp 15099573xx 192.168.0.3 0 typ host generation 0
a=candidate:28878806xx 2 tcp 15099573xx 192.168.0.3 0 typ host generation 0

[予告]

次回は、WebRTCを使って、何かします。たぶん、Torrentの考え方を応用したサンプルを紹介します。

○ソース
https://github.com/kyorohiro/HelloWebRTC/tree/master/connectStun

Tetorica FM2612 Playground を 作成しました

Tetorica FM2612 Playground を作成しました。 pages https://kyorohiro.github.io/hello_ymfm_wasm/playground/index.html https://kyorohiro.github.io/hell...