MessagePackに触れてみる

こないだの週末にMessagePackのオンラインハッカソンがあったってのは知ってたのですが、
MessagePackは自分にとっては、使ってるミドルウエアに内包されてるくらいで、
特にソレそのものをホゲホゲするあれでもなく、、。@muga_nishizawaがやってるって事で触ってみよかなー、と。
 
■ やること
 
1. JavaでHTTPクライアント作ってMessagePackでシリアライズしたデータを送信
2. Java(Spark)でサーバーを立てて取得したデータをMessagePackでデシリアライズ
3. Ruby(Sinatra)でサーバーを立てて取得したデータをMessagePackでデシリアライズ
 
1.と2.はIntelliJ IDEAで、3.はRubyMineでやっていきます。
#言語間をまたぐってのはアレなのですが、先日IntelliJに関するブログを書きましたが、
#実はその時のJetBrainsの75%オフセールでRubyMineのライセンスも買いました。
#どうも調べてくと、IntelliJとRubyMineは同じコードベースで、IntelliJにはRubyMineのプラグインが
#あるっちゅうことで、RubyMineのライセンス要らなかったじゃんって感じなのですが、
#せっかく買ったので使ってみたいなと…w
 
■ JavaでHTTPクライアント
 
application/octet-streamでMessagePackでシリアライズしたHogeオブジェクトを
bodyに詰めてサーバーに送信します。
#後からみたらコンテントタイプはapplication/x-msgpackが良さげですかね~

public class MessagePackHttpClient {
    public static void main(String args[]) throws Exception{
        Hoge hoge = new Hoge();
        hoge.id = 1;
        hoge.message = "Hello Hoge!";

        DefaultHttpClient client = new DefaultHttpClient();
        HttpHost host = new HttpHost("localhost", 【ポート】);
        HttpPost post = new HttpPost("/");

        MessagePack messagePack = new MessagePack();
        ByteArrayEntity entity = new ByteArrayEntity(messagePack.write(hoge), ContentType.create("application/octet-stream"));
        post.setEntity(entity);

        HttpResponse response = client.execute(host, post);
        System.out.println(response.getStatusLine().getStatusCode());
        client.getConnectionManager().shutdown();
    }
}

ちなみにHogeオブジェクトは↓こんな感じ。@Messageアノテーション付ける。お手軽。

@Message
public class Hoge {
    public int id;
    public String message;
}

HTTPクライアント、MessagePack、Spark(サーバー用)をpom.xmlに定義。

<repositories>
    <repository>
        <id>Spark repository</id>
        <url>http://www.sparkjava.com/nexus/content/repositories/spark/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.2.3</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.msgpack</groupId>
        <artifactId>msgpack</artifactId>
        <version>0.6.7</version>
    </dependency>
    <dependency>
        <groupId>spark</groupId>
        <artifactId>spark</artifactId>
        <version>0.9.9.4-SNAPSHOT</version>
    </dependency>
</dependencies>

 
 
■ Java(Spark)でサーバーを立てて取得したデータをMessagePackでデシリアライズ
 
POSTで取得したbodyのバイト配列を取得するのにHttpServletRequestで~ってやんなきゃなのは
ちょっとめんどくちゃいなぁ。

public class SparkSample {
    public static void main(String[] args) {
        setPort(9996);
        post(new Route("/") {
            @Override
            public Object handle(Request request, Response response) {
                MessagePack messagePack = new MessagePack();
                try {
                    System.out.println(request.body());
                    HttpServletRequest req = request.raw();
                    Hoge hoge = messagePack.read(req.getInputStream(), Hoge.class);
                    System.out.println("id:" + hoge.id);
                    System.out.println("message:" + hoge.message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return "Hello";
            }
        });
    }
}


 
 
■ Ruby(Sinatra)でサーバーを立てて取得したデータをMessagePackでデシリアライズ
 
なんでしょうね、このお手軽さ。。
ただ、Javaクライアントの@Messageでシリアライズしたデータが、Rubyの中でどう解釈されてるのか
調べたいなぁ。RubyのクライアントからJavaに送るときにreadでオブジェクトにセット出来なかったりしたので。

class SinatraSample
  require 'sinatra'
  require 'msgpack'
  set :port, 9997
  post '/' do
    puts MessagePack.unpack(request.body.read)
  end
end


 
 
■ そんなこんなで、、
 
JSONで他システムとデータをやりとりする機会がココ数年すごい増えてるので、
言語をまたいでサクっと扱えるこのライブラリはナイスだな~。
 
あと、JetBrainsのプロダクト使ってくと、あんまりJavaが苦じゃない事が多いかも。
もちろんRubyMineもGemのインストールとかスゴイ楽チンだし、Sinatraを使った時の
コードの短さとかもビビりますけどね。。
 
そういえばDeNAさんの↓この本にもMessagePackの記載あったような。また読み返そうかな。

Mobageを支える技術 ~ソーシャルゲームの舞台裏~ (WEB+DB PRESS plus)
DeNA
技術評論社
売り上げランキング: 45,787

コメント

タイトルとURLをコピーしました