打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
深入理解Apache Mina (2)---- 与IoFilter相关的几个类
从名字上看知道IoFilter应该是一个过滤器,不错,它确实是一个过滤器,它和Servlet中的过滤器类似,主要用于拦截和过滤I/O操作中的各种信息。在Mina的官方文档中已经提到了IoFilter的作用:
(1)记录事件的日志(这个在本文中关于LoggingFilter的讲述中会提到)
(2)测量系统性能
(3)信息验证
(4)过载控制
(5)信息的转换 (例如:编码和解码,这个会在关于ProtocolCodecFilter的讲述中会提到)
(6)和其他更多的信息
还是上一篇文档一样,先提出几个问题,然后沿着这几个问题的思路一个一个的对IoFilter进行讲解。
(1)什么时候需要用到IoFilter,如果在自己的应用中不添加过滤器可以吗?
(2)如果在IoService中添加多个过滤器可以吗?若可以,如何进行添加,这多个过滤器是如何工作的?
(3)Mina中提供了协议编、解码器,IoFilter也可以实现IO数据的编解码功能,在实际的使用中如何选择?
在开始对上面的问题进行讨论前,为了对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的源码。
1
2
3
4
5
6
7
8
9
10
/**
* 记录会话接收信息时的信息,然后将该信息传递到过滤器链中的下一个过滤器
* */
public void messageReceived(NextFilter nextFilter, IoSession session,
Object message) {
if (SessionLog.isInfoEnabled(session)) {
SessionLog.info(session, "RECEIVED: " + message);
}
nextFilter.messageReceived(session, message);
}
LoggingFilter继承与 IoFilterAdpater,IoFilterAdpater是IoFilter的一个实现类,该类只是提供了IoFilter方法的简单实现 ----将传递到各方法中的消息转发到下一个过滤器中。你可以根据自己的需求继承IoFilterAdpater,并重写相关的方法。 LoggingFilter就是重写了上面提到的几个方法,用于记录当前的会话各种操作的日志信息。通过上面的例子,我们可以大体的了解了 IoFilter的基本功能:根据当前会话状态,来捕获和处理当前会话中所传递的消息。
IoFilter的UML图如下:
从上面的类图我们可以清晰的看到IoFilter是一个接口,它有两个具体的实现类:
IoFilterAdpater:该类提供了IoFilter所有方法的方法体,但是没有任何逻辑处理,你可以根据你具体的需求继承该类,并重写相关的方法。IoFilterAdpater是在过滤器中使用的较多的一个类。
ReferenceCountingIoFilter:该类封装IoFilter的实例,它使用监视使用该IoFilter的对象的数量,当没有任何对象使用该IoFilter时,该类会销毁该IoFilter。
IoFilterAdpater有三个子类,它们的作用分别如下:
LoggingFilter:日志工具,该类处理记录IoFilter每个状态触发时的日志信息外不对数据做任何处理。它实现了IoFilter接口的所有方法。你可以通过阅读该类的源码学习如何实现你自己的IoFilter。
ExcuterFilter:这个Mina自身提供的一个线程池,在 Mina中你可以使用这个类配置你自己的线程池,由于创建和销毁一个线程,需要耗费很多资源,特别是在高性能的程序中这点尤其重要,因此在你的程序中配置一个线程池是很重要的。它有助于你提高你的应用程序的性能。关于配置Mina的线程池在后续的文档中会给出详细的配置方法。
ProtocolFilter:该类是Mina提供的一个协议编解码器,在socket通信中最重要的就是协议的编码和解码工作,Mina提供了几个默认的编解码器的实现,在下面的例子中使用了 ObjectSerializationCodecFactory,这是Mina提供的一个Java对象的序列化和反序列化方法。使用这个编解码器,你可以在你的Java客户端和服务器之间传递任何类型的Java对象。但是对于不同的平台之间的数据传递需要自己定义编解码器,关于这点的介绍会在后续的文档中给出。
为了更加清楚的理解这个过滤器的作用我们先来看一个简单的例子,这个例子的功能就是服务器在客户端连接到服务器时创建一个会话,然后向客户端发送一个字符串(完整的源码在附件中,这里只给出程序的简要内容):
Java代码
双击代码全选1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
ServerMain:
public class ServerMain {
public static void main(String[] args) throws IOException {
SocketAddress address = new InetSocketAddress("localhost", 4321);
IoAcceptor acceptor = new SocketAcceptor();
IoServiceConfig config = acceptor.getDefaultConfig();
// 配置数据的编解码器
config.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
// 绑定服务器端口
acceptor.bind(address, new ServerHandler());
System.out.println(" 服务器开始在 8000 端口监听 .......");
}
}
ServerHandler:
public class ServerHandler extends IoHandlerAdapter {
// 创建会话
public void sessionOpened(IoSession session) throws Exception {
System.out.println(" 服务器创建了会话 ");
session.write(" 服务器创建会话时发送的信息 。");
}
// 发送信息
public void messageSent(IoSession session, Object message) throws Exception {
}
// 接收信息
public void messageReceived(IoSession session, Object message)
throws Exception {
}
}
ClientMain:
public class ClientMain {
public static void main(String[] args) {
SocketAddress address = new InetSocketAddress("localhost", 4321);
IoConnector connector = new SocketConnector();
IoServiceConfig config = connector.getDefaultConfig();
// 配置数据的编解码器
config.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
config.getFilterChain().addLast("logger", new LoggingFilter());
// 连接到服务器
connector.connect(address, new ClientHandler());
System.out.println(" 已经连接到了服务器 " + address);
}
}
ClientHandler:
public class ClientHandler extends IoHandlerAdapter {
// 发送信息
public void messageSent(IoSession session, Object message) throws Exception {
}
// 接收信息
public void messageReceived(IoSession session, Object message)
throws Exception {
System.out.println(" 客户端接收到的服务器的信息是 " + message);
}
}
其中ServerMain和ClientMain分别是服务器和客户端的主程序,ServerHandler和ClientHandler是服务器和客户端的数据处理句柄,关于IoHandler会在后面的文档中做详细的讲解,这里只是简单说明一下,IoHandler主要是对数据进行逻辑操作,也可以理解为程序的业务逻辑层。其中:
Java代码
双击代码全选1
2
3
// 配置数据的编解码器
config.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
这行代码的功能是将网络传输中的数据在发送时编码成二进制数据,解码时将二进制数据还原成一个对象或者是基本类型的数据。
Java代码
双击代码全选1
2
3
4
5
6
7
8
9
运行这个程序会得到如下结果:
已经连接到了服务器 localhost/127.0.0.1:4321
2009-7-9 23:36:46 org.apache.mina.util.SessionLog info
信息: [localhost/127.0.0.1:4321] CREATED
2009-7-9 23:36:46 org.apache.mina.util.SessionLog info
信息: [localhost/127.0.0.1:4321] OPENED
2009-7-9 23:36:46 org.apache.mina.util.SessionLog info
信息: [localhost/127.0.0.1:4321] RECEIVED:  服务器创建会话时发送的信息 。
客户端接收到的服务器的信息是  服务器创建会话时发送的信息 。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
使用 Apache MINA 2 开发网络应用
mina简单介绍
Mina框架学习笔记(四)
Apache Mina(一)
使用 Apache MINA 开发高性能网络应用程序
(转)深入理解Apache Mina (1)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服