apache-Mina学习笔记

xiaoxiao2021-02-28  82

Apache Mina       mina是apache基于socket nio的一套框架。支持基于socket NIO库的TCP/UDP应用程序的开发。 看源码发现,它底层使用了线程池的技术。即Mina本身实现了线程池,为了提高效率,可以通过自己写连接池来使用Mina。这么理解,连接池中有多个IoSession,对于每一个IoSession,Mina不会为一个IoSession起一个线程,而是利用线程池来处理,这是NIO的好处。 Mina TCP的几个重要接口: IoSession :是对底层连接的封装,对应于当前客户端到服务器端的一个TCP连接实例。连接池中保存着多个IoSession。             这个接口有如下常用的方法:                   WriteFuture write(Object message):通过这个方法发送数据。不会引起处理线程的阻塞。 IoHandler :这个接口负责编写业务逻辑,也就是接收、发送数据的地方。这也是实际开发过程中需要用户自己编写的部分代码。我们的项目中searchHub DataSource继承了该接口。             void messageReceived(IoSession session, Object message) :             接收到消息时调用的方法,message 是一个IoBuffer 类,如果你使用了协议编解码器,那么可以强制转换为你需要的类型。 这里简单的介绍一下mina的框架: IoService:这个接口是网络的入口,IoAcceptor和IoConnector都实现这个接口。 从名字上我们可以看得出来IoAcceptor是接受链接的(服务端),而IoConnector是用来链接的(客户端) IoConnector用于与服务端建立连接,每连接一个服务端就建立一个线程。 这两种线程都是通过线程池建立的。 这两个都是继承自IoService接口的抽象实现类AbstractIoService,在AbstractIoService源码中,有: IoFilter:过滤器。他是用来过滤消息的。从IoService(网络接口)出来的数据或者进入IoService(网络接口)的数据都会经过IoFilter的处理。最重要的就是日志和解码和编码。IoHandler:处理器。它是链接应用和IoFilter的桥梁,是进行业务处理的,从IoFilter出来的数据会发到IoHandler中处理。 通过例子进行学习:

目录结构:

1.服务端程序:(服务端绑定3005端口)

package com.dvn.li.main; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.log4j.Logger; import org.apache.mina.common.IdleStatus; import org.apache.mina.common.IoAcceptor; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.LineDelimiter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; import com.dvn.li.handler.Demo1ServerHandler; public class Demo1Server { private static Logger logger = Logger.getLogger(Demo1Server.class); private static int PORT = 3005; public static void main(String[] args) { IoAcceptor acceptor = null; // 创建连接 try { // 创建一个非阻塞的server端的Socket acceptor = new NioSocketAcceptor(); // 设置过滤器(使用Mina提供的文本换行符编解码器) acceptor.getFilterChain().addLast( // 添加消息过滤器 "codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset .forName("UTF-8"), LineDelimiter.WINDOWS.getValue(), LineDelimiter.WINDOWS.getValue()))); // 设置读取数据的缓冲区大小 acceptor.getSessionConfig().setReadBufferSize(2048); // 读写通道10秒内无操作进入空闲状态 acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); // 绑定逻辑处理器 acceptor.setHandler(new Demo1ServerHandler()); // 添加业务处理 // 绑定端口 acceptor.bind(new InetSocketAddress(PORT)); logger.info("服务端启动成功... 端口号为:" + PORT); } catch (Exception e) { logger.error("服务端启动异常....", e); e.printStackTrace(); } } }

服务器端的业务逻辑处理器是Demo1ServerHandler---看它的具体实现:

package com.dvn.li.handler; import java.util.Date; import org.apache.log4j.Logger; import org.apache.mina.common.IdleStatus; import org.apache.mina.common.IoHandlerAdapter; import org.apache.mina.common.IoSession; public class Demo1ServerHandler extends IoHandlerAdapter { public static Logger logger = Logger.getLogger(Demo1ServerHandler.class); @Override public void sessionCreated(IoSession session) throws Exception { logger.info("服务端与客户端创建连接..."); } @Override public void sessionOpened(IoSession session) throws Exception { logger.info("服务端与客户端连接打开..."); } @Override public void messageReceived(IoSession session, Object message) throws Exception { String msg = message.toString(); logger.info("服务端接收到的数据为:" + msg); if ("bye".equals(msg)) { // 服务端断开连接的条件 session.close(); } Date date = new Date(); String sendMess = ""; //逻辑处理 if(msg.contains("Hello")){ sendMess = "mina收到你的Hello!"; }else{ sendMess = "请跟mina say Hello!"; } session.write(sendMess+" "+date); //往客户端发送消息 } @Override public void messageSent(IoSession session, Object message) throws Exception { session.close(); logger.info("服务端发送信息成功..."); } @Override public void sessionClosed(IoSession session) throws Exception { } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { logger.info("服务端进入空闲状态..."); } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { logger.error("服务端发送异常...", cause); } }

2.客户端程序

package com.dvn.li.main; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.log4j.Logger; import org.apache.mina.common.ConnectFuture; import org.apache.mina.common.IoConnector; import org.apache.mina.common.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.LineDelimiter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.transport.socket.nio.NioSocketConnector; import com.dvn.li.handler.Demo1ClientHandler; public class MinaClient01 { private static Logger logger = Logger.getLogger(MinaClient01.class); private static String HOST = "127.0.0.1"; private static int PORT = 3005; public static void main(String[] args) { // 创建一个非阻塞的客户端程序 IoConnector connector = new NioSocketConnector(); // 设置链接超时时间 connector.setConnectTimeout(30000); // 添加过滤器 connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset .forName("UTF-8"), LineDelimiter.WINDOWS.getValue(), LineDelimiter.WINDOWS.getValue()))); // 添加业务逻辑处理器类 connector.setHandler(new Demo1ClientHandler()); IoSession session = null; try { ConnectFuture future = connector.connect(new InetSocketAddress(HOST, PORT));// 创建连接 future.awaitUninterruptibly();// 等待连接创建完成 session = future.getSession();// 获得session(可以结合连接池,从连接池获取一个session) session.write("你好, mina");// 往服务端发送消息 } catch (Exception e) { logger.error("客户端链接异常...", e); } session.getCloseFuture().awaitUninterruptibly();// 等待连接断开 connector.dispose(); } }         和服务端代码极其相似,不同的是服务端是创建NioSocketAcceptor对象,而客户端是创建NioSocketConnector对象;同样需要添加编码解码过滤器和业务逻辑过滤器; 业务逻辑过滤器代码: package com.dvn.li.handler; import org.apache.log4j.Logger; import org.apache.mina.common.IoHandlerAdapter; import org.apache.mina.common.IoSession; public class Demo1ClientHandler extends IoHandlerAdapter { private static Logger logger = Logger.getLogger(Demo1ClientHandler.class); @Override public void messageReceived(IoSession session, Object message) throws Exception { String msg = message.toString(); logger.info("客户端接收到的信息为:" + msg); } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { logger.error("客户端发生异常...", cause); } } 3.执行过程:     a.  启动服务端Demo1Server , 然后再启动客户端MinaClient01 (客户端发送的消息是“Hello,mina”)     b.  服务端接收消息并处理:如果客户端发送的消息包含hello,将 "mina收到你的Hello! "返回给客户端, 否则返回 "请跟mina say Hello!"

4.运行结果

Demo参考地址: http://blog.csdn.net/cgwcgw_/article/details/18402769

转载请注明原文地址: https://www.6miu.com/read-57064.html

最新回复(0)