1.IoService 接口
??? 作用:IoService 是创建服务的顶层接口,无论客户端还是服务端,都是从它继承实现的。
??? 常用接口为:IoService,IoAcceptor ,IoConnector
??? 常用类为:NioSocketAcceptor ,NioSocketConnector
?
2.IoFilter 接口 -- 过滤器
?? 官方文档中的作用:
??? (1)记录事件的日志(Mina默认提供了LoggingFilter)
??? (2)测量系统性能
??? (3)信息验证
??? (4)过载控制
??? (5)信息的转换(主要就是编码和解码)
??? (6)和其他更多的信息
??? 常用接口为:IoFilter ,IoFilterChainBuilder
??? 常用类为:IoFilterAdapter,DefaultIoFilterChainBuilder,ProtocolCodecFilter,LoggingFilter
??? 注:Mina 中有一个重要的设计模式-责任链模式
??? 资料阅读:http://www.iteye.com/topic/1124504
?
? 自定义编解码器
???? 编码和解码的前提就是协议的制定:比如使用 Mina 自带的根据文本换行符解码的 TextLineCodecFactory(), 如果遇到文本换行符就开始编解码!
???? 制定协议的方法:
????????????????????????? ●定长消息法
????????????????????????? ●字符定界法
????? ? ? ? ? ? ? ? ? ? ? ● 定长报文头
????? 根据协议, 把二进制数据转换成 Java 对象称为解码 (也叫做拆包);把 Java对象转换为二进制数据称为编码(也叫做打包)。
?
? 模拟根据文本换行符编解码
? ? 解码器
import java.nio.charset.Charset; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolDecoder; import org.apache.mina.filter.codec.ProtocolDecoderOutput; public class MyCodecDecoder implements ProtocolDecoder { private Charset charset = Charset.forName("UTF-8"); //allocate(int capacity,boolean useDirectBuffer)第一个参数指定初始化容量,第二个参数指定使用直接缓冲区还是 JAVA 内存堆的缓存区,默认为 false //setAutoExpand自动扩展容量 IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true); public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { //判断当前是否有数据 while (in.hasRemaining()) { byte b = in.get(); buf.put(b); if (b == '\n') { //为了读取做好准备,一般是结束buf操作,将buf写入输出流时调用 buf.flip(); byte[] msg = new byte[buf.limit()]; buf.get(msg); String message = new String(msg, charset); // 解码成功,把buf重置 buf = IoBuffer.allocate(100).setAutoExpand(true); out.write(message); } } } public void dispose(IoSession session) throws Exception { } public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception { } }
? ??
?? 编码器
import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolEncoder; import org.apache.mina.filter.codec.ProtocolEncoderOutput; public class MyCodecEncoder implements ProtocolEncoder { private Charset charset = Charset.forName("UTF-8"); public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true); CharsetEncoder ce = charset.newEncoder(); buf.putString(message.toString(), ce); // buf.put(message.toString().getBytes(charset)); //在结尾添加\r\n输出 buf.put((byte) '\r'); buf.put((byte) '\n'); buf.flip(); out.write(buf); } public void dispose(IoSession session) throws Exception { } }
?
??? 编解码器工厂类
import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFactory; import org.apache.mina.filter.codec.ProtocolDecoder; import org.apache.mina.filter.codec.ProtocolEncoder; public class MyCodecFactory implements ProtocolCodecFactory { public ProtocolDecoder getDecoder(I