读书人

关于mina的ProtocolCodecFilter运用

发布时间: 2012-09-20 09:36:50 作者: rapoo

关于mina的ProtocolCodecFilter使用
由于开始没有充分人研读mina的内部的代码,加上没有对mina的解码器和编码器进行很很多的理解,走了不少的弯路。


我本来是打算写一个这样的服务器,既能够解析流,又能够解析对象的通信机制,弄了两个

DefaultIoFilterChain.access$1200(DefaultIoFilterChain, IoFilterChain$Entry, IoSession, Object) line: 46

这个查看源码也不知道他是究竟怎么跳转,然后把第一个ProtocolCodecFilter过滤掉。



查阅mina资料,发现mina有一个多路分离的解码器:描述如下。
假设一段数据发送过来之后,需要根据某种条件决定使用哪个解码器,而不是像上面的例子,
固定使用一个解码器,那么该如何做呢?
幸好Mina 提供了org.apache.mina.filter.codec.demux 包来完成这种多路分离
—emultiplexes)的解码工作,也就是同时注册多个解码器,然后运行时依据传入的数据
决定到底使用哪个解码器来工作。所谓多路分离就是依据条件分发到指定的解码器,譬如:
上面的短信协议进行扩展,可以依据状态行来判断使用1.0 版本的短信协议解码器还是2.0
版本的短信协议解码器。

下面我们使用一个简单的例子,说明这个多路分离的解码器是如何使用的,需求如下所示:
(1.) 客户端传入两个int 类型的数字,还有一个char 类型的符号。
(2.) 如果符号是+,服务端就是用1 号解码器,对两个数字相加,然后把结果返回给客户
端。
(3.) 如果符号是-,服务端就使用2 号解码器,将两个数字变为相反数,然后相加,把结
果返回给客户端。
Demux 开发编解码器主要有如下几个步骤:
A. 定义Client 端、Server 端发送、接收的数据对象。
B. 使用Demux 编写编码器是实现MessageEncoder<T>接口,T 是你要编码的数据对象,这
个MessageEncoder 会在DemuxingProtocolEncoder 中调用。
C. 使用Demux 编写编码器是实现MessageDecoder 接口,这个MessageDecoder 会在
DemuxingProtocolDecoder 中调用。
D. 在 DemuxingProtocolCodecFactory 中调用addMessageEncoder()、addMessageDecoder()
方法组装编解码器。

MessageEncoder的接口如下所示:
public interface MessageEncoder<T> {
void encode(IoSession session, T message, ProtocolEncoderOutput out)
throws Exception;
}
你注意到消息编码器接口与在ProtocolEncoder 中没什么不同,区别就是Object message
被泛型具体化了类型,你不需要手动的类型转换了。
MessageDecoder的接口如下所示:
public interface MessageDecoder {
static MessageDecoderResult OK = MessageDecoderResult.OK;
static MessageDecoderResult NEED_DATA =
MessageDecoderResult.NEED_DATA;
static MessageDecoderResult NOT_OK = MessageDecoderResult.NOT_OK;
MessageDecoderResult decodable(IoSession session, IoBuffer in);
MessageDecoderResult decode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception;
void finishDecode(IoSession session, ProtocolDecoderOutput out)
throws Exception;
}
(1.)decodable()方法有三个返回值,分别表示如下的含义:
A. MessageDecoderResult.NOT_OK:表示这个解码器不适合解码数据,然后检查其它解码
器,如果都不满足会抛异常;
B. MessageDecoderResult.NEED_DATA:表示当前的读入的数据不够判断是否能够使用这
个解码器解码,然后再次调用decodable()方法检查其它解码器,如果都是NEED_DATA,
则等待下次输入;
C. MessageDecoderResult.OK: 表示这个解码器可以解码读入的数据, 然后则调用
MessageDecoder 的decode()方法。
这里注意decodable()方法对参数IoBuffer in 的任何操作在方法结束之后,都会复原,也就是
你不必担心在调用decode()方法时,position 已经不在缓冲区的起始位置。这个方法相当于
是预读取,用于判断是否是可用的解码器。
(2.)decode()方法有三个返回值,分别表示如下的含义:
A. MessageDecoderResult.NOT_OK:表示解码失败,会抛异常;
B. MessageDecoderResult.NEED_DATA:表示数据不够,需要读到新的数据后,再次调用
decode()方法。
C. MessageDecoderResult.OK:表示解码成功。

读书人网 >软件架构设计

热点推荐