MIna框架I/O Filter Chain层设计

I/O Filter Chain层是介于I/O Service层与I/O Handler层之间的一层,从它的命名上可以看出,这个层可以根据实际应用的需要,设置一组IoFilter来对I/O Service层与I/O Handler层之间传输数据进行过滤,任何需要在这两层之间进行处理的逻辑都可以放到IoFilter中。
我们看一下IoFilter的抽象层次设计,如图所示:b300ec586509b18e7f8162af5f24fbb78f908b0d

通过上述类图可见,要实现一个自定义的IoFilter,一般是直接实现IoFilterAdapter类。同时,Mina也给出了几类常用的开发IoFilter的实现类,如下所示:

  • LoggingFilter记录所有事件和请求
  • ProtocolCodecFilter将到来的ByteBuffer转换成消息对象(POJO)
  • CompressionFilter压缩数据
  • SSLFilter增加SSL – TLS – StartTLS支持

想要实现一个自定义的IoFilter实现类,只需要基于上述给出的几个实现类即可。
如果想要实现自己的IoFilter,可以参考如下例子:

1 public class MyFilter extends IoFilterAdapter {
2 @Override
3 public void sessionOpened(NextFilter nextFilter, IoSession session) throwsException {
4 // Some logic here...
5 nextFilter.sessionOpened(session);
6 // Some other logic here...
7 }
8}

下面通过一个例子来说明,如何使用IoFilter的实现类。

ProtocolCodecFilter
下面是Mina自带的例子,使用了ProtocolCodecFilter类:

01 package org.apache.mina.example.gettingstarted.timeserver;
02
03 import java.io.IOException;
04 import java.net.InetSocketAddress;
05 import java.nio.charset.Charset;
06
07 import org.apache.mina.core.service.IoAcceptor;
08 import org.apache.mina.core.session.IdleStatus;
09 import org.apache.mina.filter.codec.ProtocolCodecFilter;
10 import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
11 import org.apache.mina.filter.logging.LoggingFilter;
12 import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
13
14 public class MinaTimeServer {
15 /**
16 * We will use a port above 1024 to be able to launch the server with a
17 * standard user
18 */
19 private static final int PORT = 9123;
20
21 /**
22 * The server implementation. It's based on TCP, and uses a logging filter
23 * plus a text line decoder.
24 */
25 public static void main(String[] args) throws IOException {
26 // Create the acceptor
27 IoAcceptor acceptor = new NioSocketAcceptor();
28
29 // Add two filters : a logger and a codec
30 acceptor.getFilterChain().addLast("logger", new LoggingFilter());
31 acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));
32
33 // Attach the business logic to the server
34 acceptor.setHandler(new TimeServerHandler());
35
36 // Configurate the buffer size and the iddle time
37 acceptor.getSessionConfig().setReadBufferSize(2048);
38 acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
39
40 // And bind !
41 acceptor.bind(new InetSocketAddress(PORT));
42 }
43}

上面设置了两个IoFilter,关键是看如果基于文本行的消息,使用一个ProtocolCodecFilter包裹了一TextLineCodecFactory类的实例,使用起来非常容易。
构造一个ProtocolCodecFilter实例,需要实现一个ProtocolCodecFactory实例,一个ProtocolCodecFactory包含了对消息进行编解码(Codec)的逻辑,这样实现的好处是将编解码的逻辑和IoFilter解耦合。下面看一下类图:

b95041d9c07e0e9fa2db82b912cfe1b3577b0500

LoggingFilter
如果需要记录通信过程中的事件以及请求,则可以直接使用LoggingFilter类,使用方法可以参考上面的例子。

CompressionFilter
CompressionFilter是与压缩/解压缩数据相关的IoFilter,我们可以看一下该类的构造方法,如下所示:

01/**
02 * Creates a new instance which compresses outboud data and decompresses
03 * inbound data with default compression level.
04 */
05 public CompressionFilter() {
06 this(true, true, COMPRESSION_DEFAULT);
07 }
08
09 /**
10 * Creates a new instance which compresses outboud data and decompresses
11 * inbound data with the specified <tt>compressionLevel</tt>.
12 *
13 * @param compressionLevel the level of compression to be used. Must
14 */
15 public CompressionFilter(final int compressionLevel) {
16 this(true, true, compressionLevel);
17 }
18
19 /**
20 * Creates a new instance.
21 *
22 * @param compressInbound <tt>true</tt> if data read is to be decompressed
23 * @param compressOutbound <tt>true</tt> if data written is to be compressed
24 * @param compressionLevel the level of compression to be used. Must
25 */
26 public CompressionFilter(final boolean compressInbound, final booleancompressOutbound, final int compressionLevel) {
27 this.compressionLevel = compressionLevel;
28 this.compressInbound = compressInbound;
29 this.compressOutbound = compressOutbound;
30 }

基本上就构造方法参数中指定的3个参数与压缩/解压缩相关:

  • compressionLevel
  • compressInbound
  • compressOutbound

使用的时候也比较简单,只需要创建一个CompressionFilter实例,加入到Filter Chain中即可。

DefaultIoFilterChainBuilder
Mina自带的DefaultIoFilterChainBuilder可以非常容易就可以构建一个Filter Chain,默认在创建IoAcceptor和IoConnector的时候,可以直接通过他们获取到一个DefaultIoFilterChainBuilder的实例,然后调用add*方法设置IoFilter链,如下面代码中示例:

1 IoAcceptor acceptor = new NioSocketAcceptor();
2
3// Add two filters : a logger and a codec
4 acceptor.getFilterChain().addLast("logger", new LoggingFilter());
5 acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));

下面看一下来自Mina官网的表格,Mina框架也给出了一些典型的IoFilter的实现,引用如下所示:


FilterclassDescription
BlacklistBlacklistFilterBlocks connections from blacklisted remote addresses
Buffered WriteBufferedWriteFilterBuffers outgoing requests like the BufferedOutputStream does
CompressionCompressionFilter
ConnectionThrottleConnectionThrottleFilter
ErrorGeneratingErrorGeneratingFilter
ExecutorExecutorFilter
FileRegionWriteFileRegionWriteFilter
KeepAliveKeepAliveFilter
LoggingLoggingFilterLogs event messages, like MessageReceived, MessageSent, SessionOpened, …
MDC InjectionMdcInjectionFilterInject key IoSession properties into the MDC
NoopNoopFilterA filter that does nothing. Useful for tests.
ProfilerProfilerTimerFilterProfile event messages, like MessageReceived, MessageSent, SessionOpened, …
ProtocolCodecProtocolCodecFilterA filter in charge of encoding and decoding messages
ProxyProxyFilter
Reference countingReferenceCountingFilterKeeps track of the number of usages of this filter
RequestResponseRequestResponseFilter
SessionAttributeInitializingSessionAttributeInitializingFilter
StreamWriteStreamWriteFilter
SslFilterSslFilter
WriteRequestWriteRequestFilter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值