2013年2月16日土曜日

Jetty WebSocketを試してみてハマったこと

(※KK.Konさんにコメントによる指摘を頂いたので一部訂正しました 2013/03/02) 

 リアルタイム通信対戦を実現したくて,jetty-websocketを調べていた時にハマったアレコレ。

 参考にしたサイトは以下の通り。
eclipse jetty.project@github
RFC6455-The WebSocket Protocol 日本語訳
DENSO Smart Tech Award 2013#AndroidでSTAエミュレータを使用する
codehaus.org#Maven Jetty Plugin

 このエントリではサーバ・クライアント共にJavaで実装する。

 アプリケーションサーバにはJetty(v20121106)を使用する。JettyでWebSocketを扱っているブログ記事は多いのでコードに関する解説はry)

 クライアントサイドで使用するライブラリは何を使うのがいいか迷ったけど,サーバでJetty使うならクライアント側でもJettyのライブラリ使うのが現状では一番いいような希ガス。

 調べたライブラリは以下の通り。
jetty-websocket@github
TooTallNate/Java-WebSocket@github
rbaier/weberknecht@github

 今回はjetty-websocket使ったけど,もし他の使いたいならweberknechtよりはTooTallNate/java-WebSocketの方が良いかも。weberknechtはConnectionが開かなかった時に出るArrayIndexOutOfBoundsExceptionに対する処理を行なっていない。TooTallNateはこの例外処理を行なっている。

 ソースはgithubにおいてあります。(サーバサイドクライアントサイド
どちらもMaven使ってやりました。サーバ側はeclipse+WTPでもやってみたけど自分で突っ込むjarが多くて最初は戸惑う。少し試すだけならmaven使うのがいい。

 ハマったことは、

・TooTallNate・weberknechtとサーバjettyの相性
mavenにmvn jetty:stopでjettyを止めるようにする設定をpomに加えると動かなくなる
 (fixed 2013/03/02)
ていう2点 1点 (fixed 2013/03/02)。

 1点目はTooTallNateもしくはweberknechtをクライアント側で使う場合、jettyの8番台でmaven central repoにおいてある一番新しいv20121106では動かなかった(v20120910では動く)。詳しい原因はわからないが、jettyとJava-WebSocketで扱っているWebSocketのバージョンが違うのかなぁ・・・誰か詳しい人に教えてほちぃ。

 2点目はpom見てもらえば分かるんですけど、mavenコマンドからjettyサーバを止めるための設定をpomに加えると、これまたうまく動作しなくなります。これの原因もわかってない・・・ jetty止めるときはControl+Cで妥協しました。

 ちなみにmvn jetty:stopのためにpomに付け加えたのは以下のコメントアウト部分。
 pom.xmlのstopPortをserverPortと違うものにするとmvn jetty:stopのコマンドでjettyをストップできました。セキュリティの観点から?、jettyではコンテンツアクセスのポートとサーバ管理のアクセスポートを別にしているようです(ていうか通常はこのような実装?)。ポートに関して勉強不足でした。すいませんでした。
(fixed 2013/03/02)
(訂正前)

    org.mortbay.jetty
    jetty-maven-plugin
    ${jetty.version}
    
        
            /WebSocketServer
        
        
    
    

訂正後

    org.mortbay.jetty
    jetty-maven-plugin
    ${jetty.version}
    
        
            /WebSocketServer
        
        10
        hoge
        8090
    
    
        
            start-jetty
            pre-integration-test
            
                run
            
            
                0
                true
            
        
        
            stop-jetty
            post-integration-test
            
                stop
            
        
    

 以上がハマったアレコレでした。

 ちなみに実行してみた画面キャプチャは↓