Apache MINA で echo サーバを作る

ApacheDS のバックエンドなどに使われていた事から気になっていた MINA を、少し触ってみました。まず pom.xml に以下を追加。

<dependency>
  <groupId>org.apache.mina</groupId>
  <artifactId>mina-core</artifactId>
  <version>2.0.0-M4</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-jcl</artifactId>
  <version>1.5.2</version>
</dependency>

後は、ほぼこのチュートリアルの写経。変えたのは Idle になった場合にセッションを閉じるようにしたこと位。

public class EchoServer {

    private static final int PORT = 10007;

    public static void main(String[] args) throws Exception {

        SocketAcceptor acceptor = new NioSocketAcceptor();
        acceptor.setHandler(new EchoHandler());
        acceptor.getFilterChain()
                .addLast("codec",
                         new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
        // アイドルを 5 秒に設定
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 5);
        acceptor.bind(new InetSocketAddress(PORT));
        System.out.println("server started");
    }

    private static class EchoHandler extends IoHandlerAdapter {

        @Override
        public void messageReceived(IoSession session, Object message)
                throws Exception {
            session.write(String.class.cast(message));
        }

        @Override
        public void sessionIdle(IoSession session, IdleStatus status)
                throws Exception {
            session.close(true);
        }
    }
}

telnet すると

hyakushiki:sample-net takashi$ telnet localhost 10007
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hoge
hoge <-- サーバからの応答
Connection closed by foreign host.

同じもの返すだけなので、ブラウザでアクセスすると HTTP のリクエストがそのまま返ってくる。

フラグメンテーションに注意しないといけないとか色々あるものの、

  • 非同期
  • イベント型
  • フィルタチェインなどで横断的な部分の処理の差し込みも可

といったあたり、シンプルに実装出来そう、かつ手軽。

mina-example をのぞくと、EchoServer は元より、チャットや、HaikuValidator (5,7,5 になっているか) などなどあり、サンプルもそれなりにありますね。

良い感じ。