为了更好地开展App测试,需要制造一个轮子:NIO的内容。一个方法是Socket;另外一个是通过JAVA 的NIO。现在是考虑NIO。
看了学习笔记(网上下载的《MINA2学习笔记》),理念比较清楚了,还需要编程实习一阵。下面是结合MINA的学习笔记自己的一点初步理解,后面直到5.1假期会基于这个完成实际编程。
1、基本过程
服务端程序或客户端程序创建过程:
创建连接--->添加消息过滤器(编码解码等)——>添加业务处理 创建服务端最主要的就是绑定服务端的消息编码解码过滤器和业务逻辑处理器。业务逻辑处理主要就是接收消息的处理。
上面是使用文本换行符编解码的TextLineCodec过滤器。并且Handler里面连接后会一直保持(长连接),直到收到“bye”指令。
今天(20170412)使用的小例子学习。自己编辑消息进行测试,总是出现DataLength异常,通过抓包发现,示例的程序使用了TextCodecFIlter,有自己的格式要求,(长度-4字节)+(消息头-7字节)+(用户实际信息)。顺利解决这个问题。
2、Mina主要接口
Mina的三个核心接口:IoService接口,IoFilter接口和IoHandler接口:
- 第一步. 创建服务对象(客户端或服务端) ---IoService接口实现
- 第二步. 数据过滤(编码解码等) ---IOFilter接口实现
- 第三步. 业务处理 ---IoHandler接口实现
Mina的精髓是IOFilter,它可以进行日志记录,信息过滤,编码解码等操作,把数据接收发送从业务层独立出来。
创建服务对象,则是把NIO繁琐的部分进行封装,提供简洁的接口。
业务处理是我们最关心的部分,跟普通的应用程序没任何分别。
2.1 IoService接口
作用:IoService是创建服务的顶层接口,无论客户端还是服务端,都是从它继承实现的。
常用接口为:IoService,IoAcceptor,IoConnector
常用类为:NioSocketAcceptor,NioSocketConnector
在实际应用中,创建服务端和客户端的代码很简单:
创建服务端:
IoAcceptor acceptor = null;
try {
// 创建一个非阻塞的server端的Socket
acceptor= new NioSocketAcceptor();
创建客户端:
// 创建一个非阻塞的客户端程序
IoConnectorconnector = new NioSocketConnector();
参数设置常用方法:
1.IoSessionConfig getSessionConfig()
获得IoSession的配置对象IoSessionConfig,通过它可以设置Socket连接的一些选项。
a.void setReadBufferSize(int size) 这个方法设置读取缓冲的字节数,但一般不需要调用这个方法,因为IoProcessor 会自动调整缓冲的大小。你可以调用setMinReadBufferSize()、setMaxReadBufferSize()方法,这样无论IoProcessor 无论如何自动调整,都会在你指定的区间。 b.void setIdleTime(IdleStatus status,int idleTime): 这个方法设置关联在通道上的读、写或者是读写事件在指定时间内未发生,该通道就进入空闲状态。一旦调用这个方法,则每隔idleTime 都会回调过滤器、IoHandler 中的sessionIdle()方法。 c.void setWriteTimeout(int time): 这个方法设置写操作的超时时间。 d.void setUseReadOperation(boolean useReadOperation): 这个方法设置IoSession 的read()方法是否可用,默认是false。 // 获得IoSessionConfig对象 IoSessionConfigcfg=acceptor.getSessionConfig(); // 设置读取数据的缓冲区大小() cfg.setReadBufferSize(2048); // 读写通道10秒内无操作进入空闲状态 cfg.setIdleTime(IdleStatus.BOTH_IDLE, 10); // 写操作超时时间10秒 cfg.setWriteTimeout(10);
2.DefaultIoFilterChainBuildergetFilterChain()
设置ProtocolCodecFilter,使用的协议过滤器,分隔符等。
3.setHandler(IoHandler handler);
绑定的IOHandler。 4端口号、服务器地址等 服务器端: acceptor.bind( new InetSocketAddress( PORT)); //port=3005客户端:
// 添加业务逻辑处理器类
connector.setHandler(new Demo1ClientHandler());
IoSessionsession = null;
try {
ConnectFuturefuture = connector.connect(new InetSocketAddress(
HOST, PORT));// 创建连接
future.awaitUninterruptibly();// 等待连接创建完成
session= future.getSession();// 获得session
session.write("我爱你mina");// 发送消息
}catch (Exception e) {
logger.error("客户端链接异常...", e);
}
session.getCloseFuture().awaitUninterruptibly();// 等待连接断开
connector.dispose();
2.2 IOFilter接口
常用接口为:IoFilter,IoFilterChainBuilder
常用类为:IoFilterAdapter,DefaultIoFilterChainBuilder;ProtocolCodecFilter,LoggingFilter
在Mina 的官方文档中已经提到了IoFilter 的作用:
(1)记录事件的日志(Mina默认提供了LoggingFilter)
(2)测量系统性能
(3)信息验证
(4)过载控制
(5)信息的转换(主要就是编码和解码)
(6)和其他更多的信息
IoService实例会绑定一个DefaultIoFilterChainBuilder ---- 过滤器链,我们把自定义的各种过滤器(IoFilter)自由的插放在这个过滤器链上了,类似于一种可插拔的功能!
a)插入过滤器的代码示例:
addLast()方法,还提供了addFirst(),addBefore()等方法供使用。
日志过滤器是根据IoSession的状态(创建、开启、发送、接收、异常等等)来记录会话的事件信息的!
// 设置日志过滤器
LoggingFilter lf=new LoggingFilter();
lf.setMessageReceivedLogLevel(LogLevel.DEBUG);
acceptor.getFilterChain().addLast("logger",lf);
和其它的合起来另外开一篇。
C)业务处理器示例
绑定自己的处理程序即可,主要是接收消息的处理,略。