JXTAのインストール
http://e-words.jp/w/Jxta.html
Sun Microsystems社が2001年4月に概要を発表したフレームワーク技術で、P2P型アプリケーションを容易に開発できる環境
を使ってみたかったので,使ってみました.
といってもP2P for Java / JXTAを参考に,指示通りに使ってみただけなので深みは無い.単純に動かしてみただけ.
ダウンロードとインストール
DownloadとInstallにあるとおりにやってみる.
上記のページにある「実行ファイル」から”all.zip”をダウンロードして,適当な場所に解凍する.
適当な場所に”jxta”ディレクトリに作って,all.zipの中身をコピーする.(コマンドプロンプトから指定しやすい場所が便利だと思います.今回は”D:\jxta”に入れている)
(all.zipの中身)
上記のページの指示通りにインストールする.(インストールという言葉を聞いて,.exeを想像するかも知れませんが,使いません)
(jxta\shell\shellディレクトリ)
3.jxta\shell\shellディレクトリに移動して、そこに、run1という名前のディレクトリをつくる。
4.作成した、jxta\shell\shell\run1ディレクトリに移動。
5.run1ディレクトリ内に、次のようなバッチファイルrun.batとrmfile.batを作成する。
(rub.bat)
「JAVA_HOME」は自分の持っているjdkのパスを指します.「cl」は”D:\jxta\shell\lib”にあるjarを指しています.
(D:\jxta\shell\lib)
run.batを実行するとJXTA-Shellの初期設定画面になります.先のページを参照して設定して,JXTA-Shellを起動してください.
(JXTA-Shell)
JXTAシェル・コマンドの作成
JXTA-Shell・コマンドを作成してみる.実行例はこんな感じになる.
サーバ側実行例
- -
JXTA>Shell -s
JXTA>receiver
Service advertisement was published
Waiting ......
receive message: Hello World!
Waiting ......
receive message: Hello World!
Waiting ......
receive message: Maruyama Fujio
Waiting ......
receive message: wakhok.ac.jp
Waiting ......
- -
クライアント側実行例
- -
JXTA>sender
searching for the Maruyama-1 Service advertisement
Message: "Hello World!" sent
JXTA>sender
searching for the Maruyama-1 Service advertisement
Message: "Hello World!" sent
JXTA>send Maruyama Fujio
send: cannot access Maruyama
JXTA>sender Maruyama Fujio
searching for the Maruyama-1 Service advertisement
Message: "Maruyama Fujio " sent
JXTA>sender wakhok.ac.jp
searching for the Maruyama-1 Service advertisement
Message: "wakhok.ac.jp " sent
JXTA>
- -
プログラムのソースを示す.
receiver.javaのソース
package net.jxta.impl.shell.bin.receiver; import net.jxta.impl.shell.ShellApp; import net.jxta.discovery.Discovery; import net.jxta.peergroup.PeerGroupID; import net.jxta.document.AdvertisementFactory; import net.jxta.protocol.ServiceAdvertisement; import net.jxta.protocol.PipeAdvertisement; import net.jxta.pipe.Pipe; import net.jxta.pipe.PipeID; import net.jxta.pipe.InputPipe; import net.jxta.endpoint.Message; import java.io.InputStream; public class receiver extends ShellApp { private Discovery discovery; // 探索サービス private Pipe pipes; // パイプ・サービス private InputPipe msgPipe; // 入力用パイプ・サービス private Message message; // メッセージ private PeerGroupID gid; // ピア・グループID public receiver() { } public int startApp (String[] args) { try { // パイプ・サービス告知を生成して、告知に必要なパラメータを設定する。 PipeAdvertisement pipeAdv = (PipeAdvertisement) AdvertisementFactory.newAdvertisement("jxta:PipeAdvertisement"); // パイプ・サービスの名前の設定 pipeAdv.setName("Pipe Maruyama-1"); // ネット・ピア・グループのIDはユニークであることが保証されているので // それを使って、ユニークなパイプIDを生成し、設定する。 pipeAdv.setPipeID(new PipeID(group.getID())); // サービス告知を生成して、告知に必要なパラメータを設定する。 ServiceAdvertisement serviceAdv = (ServiceAdvertisement) AdvertisementFactory.newAdvertisement ("jxta:ServiceAdvertisement"); // サービスの名前の設定 serviceAdv.setName("Maruyama-1"); // サービスのプロバイダ名の設定 serviceAdv.setProvider("wakhok.ac.jp"); // サービスのバージョン設定 serviceAdv.setVersion("Version 1.0"); // サービス告知の中にパイプ・サービス告知を設定する。 serviceAdv.setPipe(pipeAdv); // サービス告知ができたので、これをローカル・キャッシュと // ネットワーク上に公開する。 discovery = group.getDiscovery(); // ローカル・キャッシュへの公開。 discovery.publish(serviceAdv, Discovery.ADV); // ネットワーク上での公開。 discovery.remotePublish(serviceAdv, Discovery.ADV); // ピア・グループから、パイプ・サービスを獲得し、先に作った // パイプ・サービス告知を利用して、入力用のパイプを生成する。 println("Service advertisement was published" ); pipes = group.getPipe(); msgPipe = pipes.createInputPipe(pipeAdv); } catch (Exception ex) { ex.printStackTrace(); System.err.println("receiver: Error publishing the service"); } // パイプからの入力の間、繰り返す。 while (true) { println("Waiting ......"); try { // メッセージがくるのを待つ。 message = msgPipe.waitForMessage(); } catch (Exception e) { System.err.println("Error listening"); msgPipe.close(); return 1; } // メッセージの中身を取り出すためにストリームを作る。 // そのとき、サーバとクライアントはタグ名を共有しなければ //ならない。今回は、"HelloTag"というタグである。 try { // メッセージからタグ部分を取り出す。 InputStream info = message.pop ("HelloTag"); if (info != null) { byte[] msgbuffer = new byte [info.available()]; int n = info.read (msgbuffer); println("receive message: " + new String(msgbuffer)); info.close(); } else System.err.println("receiver: no tag"); } catch (Exception e) { System.err.println("receiver: error "); } } } public void stopApp () { } }
sender.javaのソース
package net.jxta.impl.shell.bin.sender; import net.jxta.impl.shell.ShellApp; import net.jxta.discovery.Discovery; import net.jxta.peergroup.PeerGroup; import net.jxta.document.AdvertisementFactory; import net.jxta.endpoint.Message; import net.jxta.pipe.Pipe; import net.jxta.pipe.PipeID; import net.jxta.pipe.OutputPipe; import net.jxta.id.ID; import net.jxta.protocol.ServiceAdvertisement; import net.jxta.protocol.PipeAdvertisement; import java.io.InputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Enumeration; public class sender extends ShellApp { private Discovery discovery; // 探索サービス private Pipe pipes; // パイプ・サービス private OutputPipe msgPipe; // 出力用パイプ private Message message; // メッセージ public sender() { } public int startApp (String[] args) { try { // Shellコマンドの引数を連結してメッセージ文字列を作成する。 String strings = ""; if ((args == null) || (args.length < 1)) { strings = "Hello World!"; } else { for( int i=0; i<args.length; i++ ) strings += args[i] + " "; } // サービス告知を見つけ出す探索サービスを、ピア・グループから獲得する。 discovery = group.getDiscovery(); // ほかのピアのサービス告知を見つけるまでループ。 println( "searching for the Maruyama-1 Service advertisement"); Enumeration enum = null; while (true) { try { // まず、ローカル・キャッシュでサービス告知を探索する。 // 名前は、"Maruyama-1"。 enum = discovery.getLocalAdvertisements( Discovery.ADV, "Name", "Maruyama-1"); // ローカルに見つかれば成功。ループを抜ける. if ((enum != null) && enum.hasMoreElements()) break; // ローカルに見つからなければ、ネットワーク上でサービス告知を // 探索する。リモートの探索は、非同期的に行われるので、 // どれくらい時間がかかるかは分からない。 // 適当に休んでいてよい。リモートの探索結果は、 // ローカル・キャッシュに必ず反映される。 discovery.getRemoteAdvertisements( null, Discovery.ADV, "Name", "Maruyama-1",1); try { Thread.sleep(2000); } catch (Exception e){} } catch (Exception e){} } // 発見されたサービス告知の中から、パイプ・サービスの告知を取り出す。 ServiceAdvertisement serviceAdv = (ServiceAdvertisement) enum.nextElement(); PipeAdvertisement pipeAdv = serviceAdv.getPipe(); // ピア・グループから、パイプ・サービスを獲得し、 // 先に取り出したパイプ・サービスの告知を利用して、 // ほかのピアに接続している「出力パイプ」と // 空のメッセージを生成する。 pipes = group.getPipe(); msgPipe = pipes.createOutputPipe( pipeAdv, Pipe.NonBlocking, 5000); message = pipes.createMessage(); // メッセージ用文字列をストリームに変え、 // "HelloTag"というタグを付けてメッセージ // に押し込んで、パイプに送り出す。 ByteArrayInputStream info = new ByteArrayInputStream (strings.getBytes()); message.push ("HelloTag", info); msgPipe.send (message); println("Message: \"" + strings + "\" sent"); } catch (Exception ex) { ex.printStackTrace(); System.err.println("Error sending message"); } return ShellApp.appNoError; } public void stopApp () { } }
D:\jxta\shell\shell\以下にsender.javaとreceiver.javaを置いて,D:\jxta\shell\shell\classというディレクトリを作ります.
このソースをコンパイルするときはコマンドプロンプトから
D:\jxta\shell\shell\run1>javac -classpath ..\..\lib\jxta.jar;..\..\lib\jxtashell.jar -d ..\class ..\sender.java D:\jxta\shell\shell\run1>javac -classpath ..\..\lib\jxta.jar;..\..\lib\jxtashell.jar -d ..\class ..\receiver.java
とタイプしてコンパイルする.
(こんな感じになってます)
次に上で作った”run.bat”の2行目にclassディレクトリを読み込むように設定する.
編集後,run.batを実行する.
これでJXTA-Shellから「receiver」,「sender」コマンドを実行できる.