Mina是Apache下的一个网络应用程序框架,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序。它提供了一个通过Java NIO在不同的传输协议上抽象的事件驱动的异步API,例如TCP/IP和UDP/IP。

还没了解原理之前,我们先从官网例子改写一下,从实践开始。我记得入行前有个前辈说过,学习任何新技术,不要先急着了解其原理,先找个例子实践一下。我觉得相当正确,因为没有谁在学习自行车前,是先把自行车运行原理弄清楚的。

依赖:jdk1.7

开发环境:ideaIU-14.1.4

测试环境:win7

建立maven工程MinaDemo,在pom.xml配置文件添加必要的依赖:

​?​

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

​<?​​​​xml​​​​version​​​​=​​​​"1.0"​​​​encoding​​​​=​​​​"UTF-8"​​​​?>​​​​<​​​​project​​​​xmlns​​​​=​​​​"​​http://maven.apache.org/POM/4.0.0​​"​​​​​​​​xmlns:xsi​​​​=​​​​"​​http://www.w3.org/2001/XMLSchema-instance​​"​​​​​​​​xsi:schemaLocation​​​​=​​​​"​​http://maven.apache.org/POM/4.0.0​​ ​​http://maven.apache.org/xsd/maven-4.0.0.xsd​​"​​​​>​​​​​​​​<​​​​modelVersion​​​​>4.0.0</​​​​modelVersion​​​​>​​​​​​​​<​​​​groupId​​​​>MinaDemo</​​​​groupId​​​​>​​​​​​​​<​​​​artifactId​​​​>MinaDemo</​​​​artifactId​​​​>​​​​​​​​<​​​​version​​​​>1.0-SNAPSHOT</​​​​version​​​​>​​​​​​​​<​​​​dependencies​​​​>​​​​​​​​<​​​​dependency​​​​>​​​​​​​​<​​​​groupId​​​​>org.apache.mina</​​​​groupId​​​​>​​​​​​​​<​​​​artifactId​​​​>mina-core</​​​​artifactId​​​​>​​​​​​​​<​​​​version​​​​>2.0.9</​​​​version​​​​>​​​​​​​​</​​​​dependency​​​​>​​​​​​​​</​​​​dependencies​​​​>​​​​</​​​​project​​​​>​


TimeServer.java类:

​?​

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

​package​​​​com.mangocool.mina;​​​​import​​​​java.io.IOException;​​​​import​​​​java.net.InetSocketAddress;​​​​import​​​​java.nio.charset.Charset;​​​​import​​​​org.apache.mina.core.service.IoAcceptor;​​​​import​​​​org.apache.mina.core.session.IdleStatus;​​​​import​​​​org.apache.mina.filter.codec.ProtocolCodecFilter;​​​​import​​​​org.apache.mina.filter.codec.prefixedstring.PrefixedStringCodecFactory;​​​​import​​​​org.apache.mina.filter.logging.LoggingFilter;​​​​import​​​​org.apache.mina.transport.socket.nio.NioSocketAcceptor;​​​​/**​​​​​​​​* Created by MANGOCOOL on 2015/10/20.​​​​​​​​*/​​​​public​​​​class​​​​TimeServer {​​​​​​​​private​​​​static​​​​final​​​​int​​​​PORT = ​​​​9123​​​​;​​​​​​​​public​​​​static​​​​void​​​​main(String[] args) ​​​​throws​​​​IOException​​​​​​​​{​​​​​​​​// 创建服务监听器,6是IoProcessor的线程数 ​​​​​​​​IoAcceptor acceptor = ​​​​new​​​​NioSocketAcceptor(​​​​6​​​​);​​​​​​​​// 增加日志过滤器​​​​​​​​acceptor.getFilterChain().addLast(​​​​"logger"​​​​, ​​​​new​​​​LoggingFilter());​​​​​​​​// 增加编码过滤器,统一编码UTF-8​​​​​​​​acceptor.getFilterChain().addLast(​​​​"codec"​​​​, ​​​​new​​​​ProtocolCodecFilter(​​​​new​​​​PrefixedStringCodecFactory(Charset.forName(​​​​"UTF-8"​​​​))));​​​​​​​​// 设置服务端逻辑处理器​​​​​​​​acceptor.setHandler(​​​​new​​​​TimeServerHandler());​​​​​​​​// 设置读缓存大小​​​​​​​​acceptor.getSessionConfig().setReadBufferSize(​​​​2048​​​​);​​​​​​​​// 设置指定类型的空闲时间,空闲时间超过这个值将触发sessionIdle方法​​​​​​​​acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, ​​​​10​​​​);​​​​​​​​// 绑定端口​​​​​​​​acceptor.bind(​​​​new​​​​InetSocketAddress(PORT));​​​​​​​​}​​​​}​


TimeServerHandler.java类:

​?​

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

​package​​​​com.mangocool.mina;​​​​import​​​​java.util.Date;​​​​import​​​​org.apache.mina.core.service.IoHandler;​​​​import​​​​org.apache.mina.core.session.IdleStatus;​​​​import​​​​org.apache.mina.core.session.IoSession;​​​​/**​​​​​​​​* Created by MANGOCOOL on 2015/10/20.​​​​​​​​*/​​​​public​​​​class​​​​TimeServerHandler ​​​​implements​​​​IoHandler {​​​​​​​​@Override​​​​​​​​public​​​​void​​​​exceptionCaught(IoSession session, Throwable throwable) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​throwable.printStackTrace();​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​messageReceived(IoSession session, Object message) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​String str = message.toString();​​​​​​​​System.out.println(​​​​"server端接收到的消息:"​​​​+ str);​​​​​​​​if​​​​(str.trim().equalsIgnoreCase(​​​​"exit"​​​​))​​​​​​​​{​​​​​​​​session.close(​​​​true​​​​);​​​​​​​​return​​​​;​​​​​​​​}​​​​​​​​Date date = ​​​​new​​​​Date();​​​​​​​​session.write(date.toString());​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​messageSent(IoSession session, Object message) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"server端发送信息:"​​​​+ message.toString());​​​​​​​​}​​​​​​​​public​​​​void​​​​inputClosed(IoSession session) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"server端:"​​​​+ session.getId() + ​​​​" 关闭输入"​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionClosed(IoSession session) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"server端IP:"​​​​+ session.getRemoteAddress().toString() + ​​​​" 关闭连接"​​​​);​​​​​​​​System.exit(​​​​0​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionCreated(IoSession session) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"server端IP:"​​​​+ session.getRemoteAddress().toString() + ​​​​" 创建连接"​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionIdle(IoSession session, IdleStatus status) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"server端闲置连接:会话 "​​​​+ session.getId() + ​​​​" 被触发 "​​​​+ session.getIdleCount(status) + ​​​​" 次"​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionOpened(IoSession session) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"server端打开连接"​​​​);​​​​​​​​}​​​​}​


public void exceptionCaught(IoSession session, Throwable cause)    当接口中其他方法抛出异常未被捕获时触发此方法。

public void messageReceived(IoSession session, Object message)    当接收到客户端的请求信息后触发此方法。

public void messageSent(IoSession session, Object message)    当信息已经发送至客户端后触发此方法。

public void inputClosed(IoSession session)    当信息接收被关闭输入时触发次方法。

public void sessionClosed(IoSession session)    当连接被关闭时触发,例如客户端程序意外退出等。

public void sessionCreated(IoSession session)    当一个新客户端连接后触发此方法。

public void sessionIdle(IoSession session, IdleStatus status)    当连接空闲时触发此方法。

public void sessionOpened(IoSession session)    当连接后打开时触发此方法,一般此方法与 sessionCreated 会被同时触发。

本类实现的是IoHandler接口,所以覆盖了IoHandler接口的所有方法。这里可以继承抽象类IoHandlerAdapter,根据业务的需要实现需要的方法。

TimeClient.java类:

​?​

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

​package​​​​com.mangocool.mina;​​​​import​​​​org.apache.mina.core.future.ConnectFuture;​​​​import​​​​org.apache.mina.core.service.IoConnector;​​​​import​​​​org.apache.mina.core.session.IoSession;​​​​import​​​​org.apache.mina.filter.codec.ProtocolCodecFilter;​​​​import​​​​org.apache.mina.filter.codec.prefixedstring.PrefixedStringCodecFactory;​​​​import​​​​org.apache.mina.filter.logging.LoggingFilter;​​​​import​​​​org.apache.mina.transport.socket.nio.NioSocketConnector;​​​​import​​​​java.net.InetSocketAddress;​​​​import​​​​java.nio.charset.Charset;​​​​import​​​​java.util.Scanner;​​​​/**​​​​​​​​* Created by MANGOCOOL on 2015/10/20.​​​​​​​​*/​​​​public​​​​class​​​​TimeClient {​​​​​​​​private​​​​static​​​​final​​​​int​​​​PORT = ​​​​9123​​​​;​​​​​​​​public​​​​static​​​​void​​​​main(String[] args)​​​​​​​​{​​​​​​​​// 创建客户端连接​​​​​​​​IoConnector connector = ​​​​new​​​​NioSocketConnector();​​​​​​​​// 增加日志过滤器​​​​​​​​connector.getFilterChain().addLast(​​​​"logger"​​​​, ​​​​new​​​​LoggingFilter());​​​​​​​​// 增加编码过滤器,统一编码UTF-8​​​​​​​​connector.getFilterChain().addLast(​​​​"codec"​​​​, ​​​​new​​​​ProtocolCodecFilter(​​​​new​​​​PrefixedStringCodecFactory(Charset.forName(​​​​"UTF-8"​​​​))));​​​​​​​​// 设置客户端逻辑处理器​​​​​​​​connector.setHandler(​​​​new​​​​TimeClientHandler());​​​​​​​​// 连接​​​​​​​​ConnectFuture connectFuture = connector.connect(​​​​new​​​​InetSocketAddress(​​​​"localhost"​​​​, PORT));​​​​​​​​// 等待建立连接​​​​​​​​connectFuture.awaitUninterruptibly();​​​​​​​​// 获取连接会话​​​​​​​​IoSession session = connectFuture.getSession();​​​​​​​​// 等待输入​​​​​​​​Scanner sc = ​​​​new​​​​Scanner(System.in);​​​​​​​​System.out.println(​​​​"客户端内容输入:"​​​​);​​​​​​​​boolean​​​​exit = ​​​​false​​​​;​​​​​​​​// 输入exit,退出系统​​​​​​​​while​​​​(!exit)​​​​​​​​{​​​​​​​​String str = sc.next();​​​​​​​​session.write(str);​​​​​​​​if​​​​(str.equalsIgnoreCase(​​​​"exit"​​​​))​​​​​​​​{​​​​​​​​exit = ​​​​true​​​​;​​​​​​​​session.close(​​​​true​​​​);​​​​​​​​}​​​​​​​​}​​​​​​​​}​​​​}​


TimeClientHandler.java类:

​?​

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

​package​​​​com.mangocool.mina;​​​​import​​​​org.apache.mina.core.service.IoHandler;​​​​import​​​​org.apache.mina.core.session.IdleStatus;​​​​import​​​​org.apache.mina.core.session.IoSession;​​​​/**​​​​​​​​* Created by MANGOCOOL on 2015/10/20.​​​​​​​​*/​​​​public​​​​class​​​​TimeClientHandler ​​​​implements​​​​IoHandler {​​​​​​​​@Override​​​​​​​​public​​​​void​​​​exceptionCaught(IoSession session, Throwable throwable) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​throwable.printStackTrace();​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​messageReceived(IoSession session, Object message) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"client端接收信息:"​​​​+ message.toString());​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​messageSent(IoSession session, Object message) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"client端发送信息:"​​​​+ message.toString());​​​​​​​​}​​​​​​​​public​​​​void​​​​inputClosed(IoSession session) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"client端:"​​​​+ session.getId() + ​​​​" 关闭输入"​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionClosed(IoSession session) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"client端与:"​​​​+ session.getRemoteAddress().toString() + ​​​​" 关闭连接"​​​​);​​​​​​​​System.exit(​​​​0​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionCreated(IoSession session) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"client端与:"​​​​+ session.getRemoteAddress().toString() + ​​​​" 建立连接"​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionIdle(IoSession session, IdleStatus status) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"client端闲置连接:会话 "​​​​+ session.getId() + ​​​​" 被触发 "​​​​+ session.getIdleCount(status) + ​​​​" 次"​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionOpened(IoSession session) ​​​​throws​​​​Exception​​​​​​​​{​​​​​​​​System.out.println(​​​​"client端打开连接"​​​​);​​​​​​​​}​​​​}​


自定义过滤器MyFilter.java类:


​?​

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

​package​​​​com.mangocool.mina;​​​​import​​​​org.apache.mina.core.filterchain.IoFilter;​​​​import​​​​org.apache.mina.core.filterchain.IoFilterChain;​​​​import​​​​org.apache.mina.core.session.IdleStatus;​​​​import​​​​org.apache.mina.core.session.IoSession;​​​​import​​​​org.apache.mina.core.write.WriteRequest;​​​​/**​​​​​​​​* Created by MANGOCOOL on 2015/10/27.​​​​​​​​*/​​​​public​​​​class​​​​MyFilter ​​​​implements​​​​IoFilter {​​​​​​​​@Override​​​​​​​​public​​​​void​​​​init() ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter init..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​destroy() ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter destroy..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​onPreAdd(IoFilterChain ioFilterChain, String s, NextFilter nextFilter) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter onPreAdd..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​onPostAdd(IoFilterChain ioFilterChain, String s, NextFilter nextFilter) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter onPostAdd..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​onPreRemove(IoFilterChain ioFilterChain, String s, NextFilter nextFilter) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter onPreRemove..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​onPostRemove(IoFilterChain ioFilterChain, String s, NextFilter nextFilter) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter onPostRemove..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionCreated(NextFilter nextFilter, IoSession ioSession) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter sessionCreated..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionOpened(NextFilter nextFilter, IoSession ioSession) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter sessionOpened..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionClosed(NextFilter nextFilter, IoSession ioSession) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter sessionClosed..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​sessionIdle(NextFilter nextFilter, IoSession ioSession, IdleStatus idleStatus) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter sessionIdle..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​exceptionCaught(NextFilter nextFilter, IoSession ioSession, Throwable throwable) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter exceptionCaught..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​inputClosed(NextFilter nextFilter, IoSession ioSession) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter inputClosed..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​messageReceived(NextFilter nextFilter, IoSession ioSession, Object o) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter messageReceived..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​messageSent(NextFilter nextFilter, IoSession ioSession, WriteRequest writeRequest) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter messageSent..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​filterClose(NextFilter nextFilter, IoSession ioSession) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter filterClose..."​​​​);​​​​​​​​}​​​​​​​​@Override​​​​​​​​public​​​​void​​​​filterWrite(NextFilter nextFilter, IoSession ioSession, WriteRequest writeRequest) ​​​​throws​​​​Exception {​​​​​​​​System.out.println(​​​​"MyFilter filterWrite..."​​​​);​​​​​​​​}​​​​}​


MyFilter可以跟日志过滤器和编码过滤器一样,被添加到客户端和服务端,对应方法的实现,可以根据业务做对应的处理。

MINA还提供了一个IoFilterAdapter类,我们编写自己的Filter时,也可以扩展IoFilterAdapter,根据业务实现须要的方法即可,不用直接实现IoFilter接口。

测试,启动服务端TimeServer、客户端TimeClient开始测试,结果如下:

Mina简单的入门示例_ios

Mina简单的入门示例_java_02




http://mangocool.com/1445415396806.html