2007年11月14日

takushimaThree Ringsフレームワークを使う(第2回)

こんにちは、多久島です。

前回はThree Ringsフレームワークの概要について書きました。今回は開発環境を用意して最小のサーバとクライアントを作ってみたいと思います。

ビルド環境の構築

用意するのは標準的なJavaアプリケーションの開発環境です。説明はWindows上で行いますがUnixを使うこともできます。後でふれますが Windowsではソースからビルドするためにパッチが必要です。Three Ringsフレームワーク的にはUnixが推奨環境なのかもしれません。

1. JDKとEclipseを入手する

まずJDK 5をインストールしてください。 NetBeansやJava EEの付属しないバージョンで結構です。JDK 6では動作確認されていないようです。5を使いましょう。

次にEclipseをインストールしてください。私は3.2を使っていますが 3.3(Europa)も使えます。Eclipseを起動して c:\workspace にワークスペースを作っておきましょう。以後このフォルダに対して作業していきます。

加えてThree Ringsフレームワークを使うアプリケーションを実行するにはJRE 1.5を使用しなければなりません。 Window→Preferences… からJRE 1.5を追加、選択しておいてください。

Installed JREs

2. Game Gardens toolkitを入手する

Game GardensのDownload the Toolkitの節からgame-gardens.zipをダウンロードし先ほど作成したワークスペースに展開します。

workspaceディレクトリ

Game GardensのWikiでは異なるインストール方法が説明されていますが、ここではtoolkitに含まれるビルド済みのThree Ringsフレームワークだけを使うのでこれでかまいません。

ソースからビルドしたい方へ(発展編)

本格的に開発することになればソースコードを参照する必要が出てくるでしょう。Game Gardens toolkitのリポジトリにはThree Ringsフレームワークがほぼ全て含まれているので、Three Rings社サイトのcodeページからライブラリ別に取得するよりこちらを使うほうが便利です。

ところがWindows上ではビルドが 通りません。解決するパッチを用意してみました。TortoiseSVNのApply Patchコマンドを使い適用できます。変更点はシンボリックリンクへの参照を元ファイルに置き換える、シグナル取得用のネイティブライブラリをコンパイ ルしないなどです。その場しのぎの対応ですので運用環境はWindowsではなくUnixにしておくことをおすすめします。

サーバとクライアントを作る

それではプロジェクトを新規作成…はやめておきます。プロジェクトの作成とコーディングは済ませておきました。 ;-) スケルトンプロジェクトをダウンロードしてワークスペースに展開、 File→Import… から skelton を指定してインポートしてみてください。

このように表示されProblemsウィンドウにエラーが出ていなければ成功です。

Eclipseのウィンドウ

(注) 外部JARファイルの参照を絶対パスで行っているのでGame Gardens toolkitなどの配置先が異なるとビルドできません。その場合はプロジェクトのプロパティを開きJava Build PathのLibrariesタブからJARファイルを追加しなおしてください。追加するファイルは game-gardens/game/lib フォルダにある narya-base.jar、narya-distrib.jar、samskivert.jarの3つです。

早速実行してみましょう。TestServer.java(サーバ)とTestClient.java(クライアント)をそれぞれ右クリックして Debug As→Java Application するとデバッグ実行できます。

Java Applicationの実行

サーバの実行結果:

サーバの実行結果

クライアントの実行結果:

クライアントの実行結果

何もないウィンドウが表示されるだけで面白くありませんが、コンソールの出力がスクリーンショットと同じであればサーバとクライアントが接続できた証拠で す。例外と共に”Unsupported major.minor version 49.0″と出力された場合は、JRE 1.5を使うようにEclipseの設定を見直してみてください。

ソースコードを読む

これで終わってはあんまりなのでサーバとクライアントのソースコードを読んでみましょう。短いので全文掲載します。

TestServer.java

import java.util.logging.Level;
import java.util.logging.Logger;
import com.threerings.presents.server.PresentsServer;

public class TestServer extends PresentsServer {

	public static void main(String[] args) {
		TestServer server = new TestServer();
		try {
			server.init();
			server.run();
		} catch (Exception e) {
			log.warning("Unable initialize server");
			log.log(Level.WARNING, e.getMessage(), e);
		}
	}

	private static final Logger log = Logger.getLogger(TestServer.class.getName());
}

これだけでクライアントの接続を受け入れられるようになります。短いのも当然で全ての実装はPresentsServerにあるためです。 PresentsServerはnaryaパッケージにあるサーバの基本クラスになります。init、runの呼び出しでコネクション、クライアントオブ ジェクト、RPC、分散オブジェクトなどを管理するマネージャの用意と、クライアントから送られてくるメッセージの処理を行います。

TestClient.java

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import com.samskivert.util.RunQueue;

import com.threerings.presents.client.Client;
import com.threerings.presents.net.UsernamePasswordCreds;
import com.threerings.util.Name;

public class TestClient extends JFrame implements RunQueue {

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				new TestClient().setVisible(true);
			}
		});
	}

	public TestClient ()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(800, 600);

		logon();
	}

	public boolean isDispatchThread() {
		return SwingUtilities.isEventDispatchThread();
	}

	public void postRunnable(Runnable run) {
		SwingUtilities.invokeLater(run);
	}

	private void logon() {
		UsernamePasswordCreds creds = new UsernamePasswordCreds(new Name("test"), "test");
		Client client = new Client(creds, this);
		client.setServer("localhost", Client.DEFAULT_SERVER_PORTS);
		client.logon();
	}

	private static final long serialVersionUID = 1L;
}

ウィンドウを表示してlocalhostにあるサーバにログオンしています。Clientクラスが実際に接続を行います。重要な点はRunQueueインタフェースの実装です。サーバからクライアントに対してイベントが発生してもその場では処理されません。Runnableオブジェクトが生成されてRunQueue.postRunnableに渡されます。その後Runnable.runが呼び出されてようやく処理されます。ここではSwing のイベントディスパッチスレッドにRunnableオブジェクトの実行を任せています。

ログオン完了すら取得していませんがこれが最小のサーバとクライアントです。次回はこれを拡張していきます。

それでは、また。

Leave a Comment

Trackbacked

trackback url for this entry: http://www.pyramid-inc.net/lab/archives/36/trackback