一个简单的例子
MINA使用非常简单,笔者以前做过一段时间传统的Java Socket开发,不过一直对Java NIO不是很理解,但是MINA很快就上手了,MINA封装了NIO繁琐的部分,使你可以更专注于业务功能实现。话不多说,让我们来看一个简单的例子,一 个很常见的例子,时间服务器。(Article by Sparkle)
我们的实现目标是一个能响应多个客户端的请求,然后返回服务器当前的系统时间的功能。传统的Java Socket程序,我们需要每accept一个客户端连接,就创建一个新的线程来响应,这会令到系统整体负载能力有较大的限制,而且我们必须手工编写连接 管理等代码。让我们来看看MINA是怎么处理的。
首先我们从官方网站下载MINA 1.1,这里我们假设JDK为1.5以上的版本,如果你使用的是JDK 1.4,请下载MINA 1.0,MINA 1.0跟1.1几乎一样,但是强烈建议使用JDK 1.5以上以获得更好的性能。
解开压缩包之后,能看见很多jar包,这里暂不介绍每个包的具体作用,可以把所有包都导入项目。值得留意的是MINA使用了一个slf4j的日志库,该日志库大有取缔common-logging之势。
public class TimeServer { public static void main(String[] args) throws IOException { IoAcceptor acceptor = new SocketAcceptor(); SocketAcceptorConfig cfg = new SocketAcceptorConfig(); cfg.getFilterChain().addLast( "logger", new LoggingFilter() ); cfg.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory())); acceptor.bind( new InetSocketAddress(8123), new TimeServerHandler(), cfg); System.out.println("Time server started."); } }
这里是我们的主程序,非常简单。
首先我们需要一个IoAcceptor,这里我们选择了一个SocketAcceptor,也就是TCP协议。
然后,我们给应用加上日志过滤器和协议编码过滤器。(Article by Sparkle)
最后,我们把acceptor bind到本机的8123端口,并且使用TimeServerHandler来实现协议。
TimeServerHandler是我们实现具体业务功能的地方。
public class TimeServerHandler extends IoHandlerAdapter { public void messageReceived(IoSession session, Object msg) throws Exception { String str = (String) msg; if( "quit".equalsIgnoreCase(str) ) { session.close(); return; } Date date = new Date(); session.write( date.toString() ); System.out.println("Message written..."); } public void sessionCreated(IoSession session) throws Exception { System.out.println("Session created..."); } }
IoHandlerAdapter提供了7个事件方法,我们要做的事情仅仅是挑选我们需要做出响应的事件进行重载。在我这个例子了,我重载了两个方 法。sessionCreated会在客户端连接的时候调用,通常我们会在这里进行一些初始化操作,我这里仅仅是打印一条信息。 messageReceived就是整个Handler的中心部分,每一个从客户端发过来的消息都会转化成对该方法的调用。由于我们加入了协议编码过滤 器,因此这里获得的Object msg是一个String,而不是默认的ByteBuffer(下文会详细介绍ProtocolCodecFilter)。这里我们实现了一个很简单的业 务功能,如果用户输入的是quit,就断开连接,否则就输入当前时间。可以看出,IoSession封装了对当前连接的操作。
至此,我们就实现了一个时间服务器。