即时通讯开发Apache Mina框架之IoFilter详解

见名知义,IoFilter应该是一个过滤器,没错,它确实是一个过滤器。它和Servlet中的过滤器类似,主要用于拦截和过滤I/O操作中的各种信息。

在Mina的官方文档中已经提到了IoFilter的作用:

    (1)记录事件的日志(这个在本文中关于LoggingFilter的讲述中会提到)

    (2)测量系统性能

    (3)信息验证

    (4)过载控制

    (5)信息的转换(例如:编码和解码,这个会在关于ProtocolCodecFilter的讲述中会提到)

    (6)和其他更多的信息

先看看几个问题,然后沿着问题的思路一个一个的对IoFilter进行讲解:

    (1)什么时候需要用到IoFilter,如果在自己的应用中不添加过滤器可以吗?

    (2)如果在IoService中添加多个过滤器可以吗?若可以,如何进行添加,这多个过滤 器是如何工作的?

    (3)Mina中提供了协议编、解码器,IoFilter也可以实现IO数据的编解码功能,在实际 的使用中如何选择?

先看看 LoggingFilter

为了对IoFilter提供的方法有一个具体的了解,先对Mina自身提供的一个最简单的过滤器进行一些讲解----LoggingFilter。

首先还是看一下LoggingFilter中提供的几个方法。列举如下(方法中的参数就不再给出,完整方法的实现请参考附件中LoggingFilter的源码):

    (1)sessionCreated()
    (2)sessionOpened()
    (3)sessionClosed()
    (4)sessionIdle()
    (5)exceptionCaught()
    (6)messageReceived()
    (7)messageSent()
    (8)filterWrite()
    (9)filterClose()


这几个方法都由相应会话(或者说是连接的状态,读、写、空闲、连接的开闭等)的状态的改变来触发的。当一个会话开启时,LoggingFilter捕获到会话开启的事件,会触发sessionCreated()方法,记录该会话开启的日志信息。同样当一个会话发送数据时,Logging捕获到会话发送消息的事件会记录消息发送的日志信息。这里只是给出messageReceived()的完成方法的实现,其他方法的完整实现请参考附件中LoggingFilter的源码。

LoggingFilter继承与IoFilterAdpater,IoFilterAdpater是IoFilter的一个实现类,该类只是提供了IoFilter方法的简单实现----将传递到各方法中的消息转发到下一个过滤器中。你可以根据自己的需求继承IoFilterAdpater,并重写相关的方法。LoggingFilter就是重写了上面提到的几个方法,用于记录当前的会话各种操作的日志信息。即时通讯聊天软件app开发可以加蔚可云的v:weikeyun24咨询

IoFilter讲解

通过上面的例子,我们可以大体的了解了IoFilter的基本功能:根据当前会话状态,来捕获和处理当前会话中所传递的消息。

我们可以清晰的看到IoFilter是一个接口,它有两个具体的实现类: IoFilterAdpater:该类提供了IoFilter所有方法的方法体,但是没有任何逻辑处理,你可以根据你具体的需求继承该类,并重写相关的方法。IoFilterAdpater是在过滤器中使用的较多的一个类。

ReferenceCountingIoFilter:该类封装IoFilter的实例,它使用监视使用该IoFilter的对象的数量,当没有任何对象使用该IoFilter时,该类会销毁该IoFilter。

IoFilterAdpater有三个子类,它们的作用分别如下: LoggingFilter:日志工具,该类处理记录IoFilter每个状态触发时的日志信息外不对数据做任何处理。它实现了IoFilter接口的所有方法。你可以通过阅读该类的源码学习如何实现你自己的IoFilter。

ExcuterFilter:这个Mina自身提供的一个线程池,在Mina中你可以使用这个类配置你自己的线程池,由于创建和销毁一个线程,需要耗费很多资源,特别是在高性能的程序中这点尤其重要,因此在你的程序中配置一个线程池是很重要的。它有助于你提高你的应用程序的性能。

ProtocolFilter:该类是Mina提供的一个协议编解码器,在socket通信中最重要的就是协议的编码和解码工作,Mina提供了几个默认的编解码器的实现,在下面的例子中使用了ObjectSerializationCodecFactory,这是Mina提供的一个Java对象的序列化和反序列化方法。使用这个编解码器,你可以在你的Java客户端和服务器之间传递任何类型的Java对象。但是对于不同的平台之间的数据传递需要自己定义编解码器。

IoFilter在MINA中的真正作用

在上面的例子中我们清楚了整个IoFilter或者是IoFilter的工作流程,那么IoFilter在Mina中的作用如何?所有的数据在发送到Mina程序中时,数据都是先通过IoFilter,经过处理后再转发到业务层。这里IoFilter就起到了一个承上启下的作用。

到这里我们就可以回答本文开始提到的问题了:

    (1)什么时候需要用到IoFilter,如果在自己的应用中不添加过滤器可以吗?
      在你自己的程序中可以添加过滤器,也可以不添加,但是在数据发送之前,所发送的数据必须转换成二进制数据,这个可以有IoFilter完成,也可以由ProtocolCodecFilter完成(关于这个问题会在后面的文章中详细讲述),否则Mina会抛出Write requests must be transformed to class org.apache.mina.common.ByteBuffer:异常。这是因为网络中传输的数据只能是二进制数据。因此无论添加不添加过滤器,都必须将要发送的数据转换成二进制数据。
    (2)如果在IoService中添加多个过滤器可以吗?若可以,如何进行添加,这多个过滤 器是如何工作的?
      在IoService中可以添加多个过滤器,这个在上面的程序中已经给处理,添加的方式也很简单,通过程序一目了然。
    (3)Mina中提供了协议编、解码器,IoFilter也可以实现IO数据的编解码功能,在实际的使用中如何选择?
      Mina的编解码器在Mina的使用中是最关键的一个问题,特别是在不同语言之间进行通信的时候,比如Java和C/C++等,由于Mina自身没有提供这些编解码器,所以需要自己来实现。Mina提供了一个Decoder/Encoder,你可以实现两个类来完成不同平之间的通信。

猜你喜欢

转载自blog.csdn.net/wecloud1314/article/details/127005008