マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

Java版のMessagePack-RPCを使ってみる

そろそろ手を付けなければいけないと思っていたMessagePack-RPCを使ってみる。そのうち使い方が変わるかもしれないがversion 0.5を試す。http://github.com/msgpack/msgpack-rpcにソースが上がってるので、

git clone http://github.com/msgpack/msgpack-rpc.git
する。msgpack-rpcディレクトリの中のjavaに入り

mvn compile
mvn package
でjarができるとREADMEには書いてあったのだが、読まなかったは俺は
mvn install
とやってしまった。しかしtargetというディレクトリができて、中にmsgpack-rpc-0.5.0.jarができてたのでめでたしめでたし。そしてMessagePack-RPCを使うのに必要なjarだが、以下の通りである。M2_REPOは$HOME/.m2/repositoryのはず

M2_REPO/org/msgpack/msgpack/0.4/msgpack-0.4.jar
M2_REPO/org/jboss/xnio/xnio-api/2.0.2.GA/xnio-api-2.0.2.GA.jar
M2_REPO/org/jboss/xnio/xnio-nio/2.0.2.GA/xnio-nio-2.0.2.GA.jar
mvn使えって話だろうけど、使い方がわからない俺はmsgpack-rpc-0.5.0.jarとこいつらをコピーしてコンパイル時と実行時にcpでjarを指定した。コンパイル時にはxnio関係は必要ない模様。そしてMessagePack-RPCを利用したプログラムの作成に移る。以下、ソースコードと解説。サーバプログラム、クライアントプログラム、結果の順に書く

まずサーバプログラム。EventLoopのインスタンス作って、それをServerのコンストラクタに渡す。次にReflectionDispatcherのコンストラクタでクライアントから呼び出したいメソッドを持っているオブジェクトを渡す。そのReflectionDispatcherをServer#serveに渡してServer#listenでポート番号を指定して後はクライアントの待つだけ。気をつけるのは呼び出すメソッドの返り値はvoidで、実際に返す値はRequest#sendResultにMessagePackObjectの形で渡すこと。MessagePackの使い方を知っておく必要がある。文字列ならRawType.createで数値ならIntegerType.create、浮動小数点はFloatType.createを使えばいい。doubleでもFloatType.createのオーバロードでdouble用のオブジェクトが返って来る。

import org.msgpack.object.RawType;

import org.msgpack.rpc.Server;
import org.msgpack.rpc.Request;
import org.msgpack.rpc.EventLoop;
import org.msgpack.rpc.ReflectionDispatcher;

import java.io.IOException;

public class TestServer{
    public static class TestHandler{
        public void hello(Request request){
            request.sendResult(RawType.create("Hello World!"));
        }
    }

    public static void main(String[] args){
        EventLoop loop = new EventLoop();
        Server server = new Server(loop);

        try{
            server.serve(new ReflectionDispatcher(new TestHandler()));
            server.listen(19850);

            while(true){
            }
        }catch(IOException e){
            server.close();
            loop.shutdown();
        }
    }
}

次にクライアントプログラム。ClientをJavaの普通のSocketと同じ用に初期化して、callApplyに呼びたいメソッドの名前と引数を配列で渡すだけ。返り値はMessagePackObject形式なので、as〜を呼びだす必要がある。ここらへんはMessagePackの使い方を調べないとわからないことである。

import org.msgpack.MessagePackObject;
import org.msgpack.rpc.Client;

public class TestClient{
    public static void main(String[] args) throws Exception{
        Client client = new Client("127.0.0.1", 19850);
        MessagePackObject result = client.callApply("hello", new Object[]{});

        System.out.println(result.asString());
    }
}

結果
サーバ→クライアントの順で実行し、サーバプログラムのTestHandlerのhelloが呼び出されて、Hello World!が返ってくる。クライアントはサーバが止まらない限り何度でも呼び出せる。たまにNullPointerExceptionがでるようだが、そのうち解決されるだろう。以上が自分で試したMessagePack-RPCの手順である