Mina框架研究(3)
来源:互联网 发布:网络程序员教程 编辑:程序博客网 时间:2024/05/22 05:21
http://www.cnblogs.com/xiekeli/archive/2012/11/02/2750991.html
Filters
IoFilter 是MINA框架中一个核心的部分,如下图,对间于IoService和IoHandle之间,用于过滤所有的I/O事件和请求,其扮演的角色就像J2EE中的Servlet。
MINA提供不少现成的过滤器:
1、LoggingFilter :日志过滤器,用于记录所有的事件和请求日志.
2、ProtocolCodecFilter:规约解析过滤器,用来将所有收到的ByteBuffer内容转换为POJO消息(对象),实现往来报文的编码和解码;
3、CompressionFilter:压缩过滤器;
4、SSLFilter
…
ProtocolCodecFilter
相对比较常用的是ProtocolCodecFilter,下面主要介绍一下ProtocolCodecFilter的使用:
还是以官方帮助文档中例子来说明(http://mina.apache.org/chapter-11-codec-filter.html)
这是一个图片服务器程序,请求图片的下行报文格式:
width: 请求图片的宽度
height: 请求图片的高度
numchars: 生成的字节个数
服务端返回两张图片:
length1: 图片1的大小
image1: 图片1(PNG格式)
length2: 图片2的大小
image2: 图片2(PNG格式)
public class ImageServer {
2: public static final int PORT = 33789;
3:
4: public static void main(String[] args) throws IOException {
5: ImageServerIoHandler handler = new ImageServerIoHandler();
6: NioSocketAcceptor acceptor = new NioSocketAcceptor();
7: acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new ImageCodecFactory(false)));
8: acceptor.setLocalAddress(new InetSocketAddress(PORT));
9: acceptor.setHandler(handler);
10: acceptor.bind();
11: System.out.println("server is listenig at port " + PORT);
12: }
13: }
这里先来看和Filter有关的部分:
acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new ImageCodecFactory(false)));
在acceptor的Filter链中加入我们自己的过滤器,一个ProtocolCodecFilter的实现,这里的ImageCodecFactory又是什么呢?
: public class ImageCodecFactory implements ProtocolCodecFactory {
2: private ProtocolEncoder encoder;
3: private ProtocolDecoder decoder;
4:
5: public ImageCodecFactory(boolean client) {
6: if (client) {
7: encoder = new ImageRequestEncoder();
8: decoder = new ImageResponseDecoder();
9: } else {
10: encoder = new ImageResponseEncoder();
11: decoder = new ImageRequestDecoder();
12: }
13: }
14:
15: public ProtocolEncoder getEncoder(IoSession ioSession) throws Exception {
16: return encoder;
17: }
18:
19: public ProtocolDecoder getDecoder(IoSession ioSession) throws Exception {
20: return decoder;
21: }
22: }
ImageCodecFactory是对接口ProtocolCodecFactory 的实现,是用来构建Filter的。ProtocolCodecFactory 接口只有两个方法:
1: public interface ProtocolCodecFactory {
2:
3: public ProtocolEncoder getEncoder(IoSession is) throws Exception;
4:
5: public ProtocolDecoder getDecoder(IoSession is) throws Exception;
6: }
没错,这个规约编解码工厂需要装配一个编码器(Encoder)和一个解码器(Decoder):
编码器:
1: public class ImageRequestEncoder implements ProtocolEncoder {
2:
3: public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
4: ImageRequest request = (ImageRequest) message;
5: IoBuffer buffer = IoBuffer.allocate(12, false);
6: buffer.putInt(request.getWidth());
7: buffer.putInt(request.getHeight());
8: buffer.putInt(request.getNumberOfCharacters());
9: buffer.flip();
10: out.write(buffer);
11: }
12:
13: public void dispose(IoSession session) throws Exception {
14: // nothing to dispose
15: }
16: }
解码器:
1: public class ImageRequestDecoder extends CumulativeProtocolDecoder {
2:
3: protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
4: if (in.remaining() >= 12) {
5: int width = in.getInt();
6: int height = in.getInt();
7: int numberOfCharachters = in.getInt();
8: ImageRequest request = new ImageRequest(width, height, numberOfCharachters);
9: out.write(request);
10: return true;
11: } else {
12: return false;
13: }
14: }
15: }
这里解码器不是直接从ProtocolDecoder继承的,为什么呢?因为实际中接受的一个数据包并不能保证包含完整的一帧报文,就是所谓的断帧的情况,如果用CumulativeProtocolDecoder,就不需要自己处理这种情况了,MINA框架会将未解码的数据保留,等下一包数据到来后继续尝试解码;
这里编码器的encode和解码器的doDecode方法就是实际用来进行应用层规约编解码的;其中ImageResuest是下行请求规约对应POJO.
整个类的协助关系如下图所示:
Filter过滤器处理完后,就交给Handler,做进一步业务处理;
Response部分的就不多罗嗦了,可以看这里
至此对MINA框架用过的一些东西,从使用指南的角度做了一些总结,还有很多方面还没有用过,先留一个坑,等来日填补吧。MINA框架最吸引我的是这种设计思想,将通信、规约解析、业务处理分离得恰到好处,既不影响性能又方便扩展和替换。下一步希望从源代码的角度,学习一下其内部的实现思想。
- Mina框架研究(3)
- Mina框架研究(3)
- Mina框架研究(1)
- Mina框架研究(2)
- Mina框架研究(2)
- Mina框架研究(1)
- Mina框架研究(2)
- Mina框架研究(一)
- Mina框架研究(1)
- Mina框架研究(2)
- mina框架源代码研究
- Mina框架研究
- Mina框架研究
- Mina通信框架应用3
- MINA框架学习 (一)
- MINA框架
- MINA框架
- MINA 框架
- POJ - 1276 Cash Machine(多重背包)
- Linux的伪文件系统
- R0-R37是Arm 的寄存器,就是CPU内部的。而GPIO寄存器都是外设的。换句话说,只要是arm的cpu,包括其他的公司的芯片都会有R0-R37,而GPIO的寄存器就是某个特定的芯片才有。
- uva1424 saleman
- javabean出现找不到属性值的问题解决
- Mina框架研究(3)
- 第24题 Reverse Words in a String
- 将计算机思维故事化——之操作系统典型调度算法
- How to create columns like "bigint" or "longtext" in Rails migrations
- android面试感言
- Lua学习之【3】:表达式
- android学习笔记——linux环境下android开发环境的搭建
- BarberShop-java thread Synchronizing Demo
- linux线程私有数据