vert.xでWebSocketする

| コメントをどうぞ

ある昼下がり、私は ラオウ PMからこうお達しを受けたのです。

「お前のような輩は、WebSocketを使った通知サーバーをつくればいい」

このブログは、そんな指令を受けたプログラマー4時間分の記録である。
こんにちわ、DiceK Mikamiです。
 
 

今回の目的

今回は、WebSocketを通知に利用できないかと言うところが出発点になります。
WebSocketと言えばnode.jsですが、今回はそれ以外のやり方を模索したいと思います。
具体的に実現したいことは以下のような図になります。

勘の良い方はお気づきと思いますが、Pusherと同じです。
ただし、Pusherのようなクラウドサービスにも依存したくありませんし、node.jsはまだ利用したくないという命題がありますので、第3の道としてvert.xを利用します。
 

vert.xとは

vert.xとは、「JVM上で動作する次世代の非同期でスケーラブルな並列処理アプリケーションのためのフレームワーク」だそうです。
平たく言うと、「JVM上で動作するnode.js」だと思っていただいて問題ないかと思います。
また、JVM上で動作するとありますが、開発者は複数の言語を利用することができます。
例えば、RubyやPythonなどと言った流行りの言語でも利用できます。
vert.xではSocketJSをサポートしており、これを使うことでWebSocketの利用を実現できます。
 

実装環境

  • vert.x: 1.3.0-final
  • Java: JDK1.7.0
  • Groovy: 2.0.5
  •  

groovy実装を使う

vert.xに含まれているサンプル「 eventbusburidge 」を改良して、実現したいと思います。
groovyで実装した内容は以下のようになります。

import org.vertx.groovy.core.http.RouteMatcher

def server = vertx.createHttpServer()
def route = new RouteMatcher()

route.get('/') { req ->
    req.response.sendFile('notificationserver/index.html')
}

route.get('/vertxbus.js') { req ->
    req.response.sendFile('notificationserver/vertxbus.js')
}

route.post('/deliver') { req ->
    //Postで通知内容が送られてくることを想定
    req.bodyHandler { body ->
        String channel;
        String message;
        def params = body.toString();
        for(param in params.split('&')){
            def keyval = param.split('=');
            switch(keyval[0]) {
                case 'channel':
                    //チャンネルを取得
                    channel = keyval[1] 
                    break
                case 'message':
                    //メッセージを取得
                    message = keyval[1]
                    break
            }
        }

        //受け取ったら指定チャンネルに通知する
        vertx.eventBus.send(channel, ["message": "${message}"]);
    }

    req.response.end();
}

def requestServer = server.requestHandler(route.asClosure())
def sockServer = vertx.createSockJSServer(server)
sockServer.bridge([prefix: '/notif'], [[:]], [[:]])
requestServer.listen(8080)

「 /deliver 」にPOST送信された内容を指定したチャネルに流し込むような形です。
通知を受け取るためには、受け手は前もってそのチャネルをサブスクライブしておく必要があります。
基本的な概念は非常にOpenAjaxHubに似ていると思います。
 
これ以外に通知が届かなかった場合の処理をどうするかや堅牢性を担保するための仕組みなどを組み込む必要がありますが、基本的には目的通りの動きになりました。
 

参考URL

vert.x
SockJS
Pusher
infoScoopガジェットとOpenAjax Hub
 
我がコードに一片の悔いなし!!<もういいよ
注意:この記事の枕部分は脚色されています。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>