1、什么是Apache Mina?
Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过Java NIO技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。简单的说,可以用它来帮助我们快速的开发网络通信。
2、它的工作原理?
3、如何使用Apac Mina?
3.1、创建一个Maven工程
应该如何创建Maven工程我这里就不详细介绍了,网上有很多资料大家都可以去看看。在这里我使用的是spring boot框架,所以POM文件是这样的:
4.0.0 com.springboot mina 0.0.1-SNAPSHOT jar mina Demo for mina org.springframework.boot spring-boot-starter-parent 1.2.5.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.apache.mina mina-core 2.0.4 org.springframework.boot spring-boot-maven-plugin
3.2、创建服务端程序
接着我们创建一个服务端程序,用来接收和监控传过来的信息
package com.springboot.mina.server; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.log4j.Logger; 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.textline.TextLineCodecFactory; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MyServer { private static Logger logger = Logger.getLogger(MyServer.class); //日志 private static final int port = 8899; //端口 public static void main(String[] args) { // 创建一个非阻塞的server端的socket IoAcceptor acceptor = new NioSocketAcceptor(); // 设置过滤器,选用Mina自带的过滤器一行一行读取代码 acceptor.getFilterChain().addLast("myChain", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); // 设置读取数据的缓冲区大小 acceptor.getSessionConfig().setReadBufferSize(2048); // 读写通道10秒内无操作进入空闲状态 acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10); // 绑定逻辑处理器 acceptor.setHandler(new ServerHandler()); // 绑定端口,启动服务器 try { acceptor.bind(new InetSocketAddress(port)); } catch (IOException e) { e.printStackTrace(); } logger.info("服务已启动,端口是:"+port); } }
3.3、创建服务端的逻辑处理器
在上面我们为服务端注册了一个逻辑处理器acceptor.setHandler(new ServerHandler()),用力具体处理监听动作,接下来我们就要来实现这一处理器
package com.springboot.mina.server; import org.apache.log4j.Logger; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; public class ServerHandler extends IoHandlerAdapter{ private static Logger logger = Logger.getLogger(ServerHandler.class); //创建连接 @Override public void sessionCreated(IoSession session) throws Exception { logger.info("服务器创建session连接!"); } //打开一个连接 @Override public void sessionOpened(IoSession session) throws Exception { logger.info("服务器打开session连接!"); } //关闭连接 @Override public void sessionClosed(IoSession session) throws Exception { logger.info("服务器关闭session连接!"); } //连接空闲 @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { } //有异常时 @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { logger.info("服务器出现异常"+cause); } //接收到消息 @Override public void messageReceived(IoSession session, Object message) throws Exception { String str = message.toString(); logger.info("服务器收到消息:"+str); if(str.equals("close")){ session.write("close"); session.close(true); } } //将要发送消息 @Override public void messageSent(IoSession session, Object message) throws Exception { } }
这样子我们服务端就基本搭建完成了,如果你还要实现什么逻辑处理,在逻辑处理器对应的动作方法上写就行了
3.4、创建客户端
服务端创建好了,接下来我们建一个客户端,来发送数据,当然,也可以处理从服务端发过来的信息
package com.springboot.mina.client; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.log4j.Logger; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.transport.socket.SocketConnector; import org.apache.mina.transport.socket.nio.NioSocketConnector; public class MyClient { private static Logger logger = Logger.getLogger(MyClient.class); private static final String host = "127.0.0.1"; private static final int port = 8899; public static void main(String[] args) { // 创建连接 SocketConnector connector = new NioSocketConnector(); // 设置过滤器,选用Mina自带的过滤器一行一行读取代码 connector.getFilterChain().addLast("myChain", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); // 设置连接超时时间 connector.setConnectTimeoutMillis(30 * 1000); // 绑定逻辑处理器 connector.setHandler(new ClientHandler()); // 连接到服务器 ConnectFuture future = connector.connect(new InetSocketAddress(host, port)); // 等待连接创建完成 future.awaitUninterruptibly(); // 获得session IoSession session = future.getSession(); // 发送消息 session.write("你好! \r\n close"); logger.info("客户端正在连接服务器,"+host+":"+port); // 等待连接断开 session.getCloseFuture().awaitUninterruptibly(); connector.dispose(); } }
ok,我们创建了一个客户端程序,并在session.write("你好! \r\n close")发送了一条数据,“\r\n”是换行符,我们设置的过滤器是Mina本身提供的逐行读取
3.5、创建客户端的逻辑处理器
同3.3相同,同样要为客户端注册一个逻辑处理器,甚至代码都相差不多
package com.springboot.mina.client; import org.apache.log4j.Logger; import org.apache.mina.core.service.IoHandler; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; public class ClientHandler implements IoHandler { private static Logger logger = Logger.getLogger(ClientHandler.class); // 有异常 @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { logger.info("程序出现异常"+cause); } // 接收到消息时 @Override public void messageReceived(IoSession session, Object message) throws Exception { String str = message.toString(); logger.info("客户端收到消息:"+str); if(str.equals("close")){ session.close(true); } } // 将要发送消息 @Override public void messageSent(IoSession session, Object message) throws Exception { } // 关闭连接 @Override public void sessionClosed(IoSession session) throws Exception { logger.info("客户端关闭session连接!"); } // 创建连接 @Override public void sessionCreated(IoSession session) throws Exception { logger.info("客户端创建session连接!"); } // 连接空闲 @Override public void sessionIdle(IoSession session, IdleStatus arg1) throws Exception { } // 打开一个连接 @Override public void sessionOpened(IoSession session) throws Exception { logger.info("客户端开始session连接!"); } }
好了,这样我们基于Mina的服务端和客户端就搭建完成了,因为都是写在了Main()方法里,只要右键->run as Java Application就能把程序跑起来了,你可以两个一起跑,也可以只运行服务器,打开命令行,输入
telnet 127.0.0.1 8899
就可以和端口建立通信了,在控制台就可以看到你输入的内容了。
4、Mina具体技术
程序写好了,我们来看看上面用到了Mina的哪些东西
1、类NioSocketAcceptor;创建一个服务端监听
2、类NioSocketConnecto;创建一个客户端监听
3、IoHandler接口; 封装了不同事件的处理
4、类IoSession; 用来保存会话属性和发送消息,可以理解为服务端和客户端之间的特定连接
5、类IoFilter; 用来对数据进行过滤。我们上面使用的是Mina自带的逐行读取的过滤器,如果有需要,我们要可以定义自己的过滤器
Apacha Mina官网:http://mina.apache.org/mina-project/
在线API文档:http://tool.oschina.net/apidocs/apidoc?api=mina