本文主要是介绍Mina框架在项目中的使用(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近由于项目本身的需要,正在进行Mina框架的学习,并且将其整合到正在开发的系统中。下面将会根据实际的工作情况分享一些心得感受。
一、 项目需求:
我们正在开发的系统,现在主要分为两个部分,正两个部分之间需要使用TCP Socket进行网络通讯。具体开发的难点是发送消息的部分。由于需要考虑到每次创建连接时造成的系统开销,所以使用的连接方式必须是长连接,就是保存连接,不能断开。而且在连接的另一端发生当机的情况下能够及时回复,不会就此丢掉和这一端的通讯。在连接发送消息后,能够判定另一端无法及时收到消息的情况,并且做出正确处理。
综上所述,能够整理出如下三条需求:
l 两端的连接通讯必须是长连接,不能每次重新建立。
l 在连接断开的情况下能够及时处理,并能有效恢复。
l 发送数据需要有超时机制。
我们这一阶段的Mina框架的使用便是围绕着这三条需求展开的。
二、 Mina框架相关知识简介:
在正式开始Mina框架的实际应用前,先简单介绍一些Mina的基本知识,以便于下面的实用场景分析。中间会穿插架构图和示例代码。
在介绍架构之前先认识几个接口:
IoAccepter 相当于网络应用程序中的服务器端
IoConnector 相当于客户端
IoSession 当前客户端到服务器端的一个连接实例
IoHandler 业务处理逻辑
IoFilter 过滤器用于悬接通讯层接口与业务层接口
然后可以看一下Mina的架构图,如图2-1Mina框架图所示。
在图中的模块链中,IoService便是应用程序的入口,相当于基本接口中的IoAccepter,IoAccepter便是IoService的一个扩展接口。IoService接口可以用来添加多个IoFilter,这些IoFilter符合责任链模式并由IoProcessor线程负责调用。而IoAccepter在ioService接口的基础上还提供绑定某个通讯端口以及取消绑定的接口。在日常应用中,我们可以这样使用IoAccepter:
IoAcceptor acceptor = new SocketAcceptor(); |
相当于我们使用了Socket 通讯方式作为服务的接入,当前版本的 Mina 还提供了除SocketAccepter外的基于数据报文通讯的DatagramAccepter以及基于管道通讯的VmPipeAccepter。另外还包括串口通讯接入方式,目前基于串口通讯的接入方式已经在最新测试版的MINA中提供。我们也可以自行实现IoService接口来使用自己的通讯方式。
而在上图中最右端也就是IoHandler,这便是业务处理模块。我们的项目大部分的工作也就是在这个接口的实现类中完成。在业务处理类中不需要去关心实际的通讯细节,只管处理客户端传输过来的信息即可。编写Handler类就是使用Mina开发网络应用程序的重心所在,相当于Mina已经帮你处理了所有的通讯方面的细节问题。为了简化Handler类,MINA提供了IoHandlerAdapter类,此类仅仅是实现了IoHandler接口,但并不做任何处理。
一个IoHandler接口中具有如下一些方法(摘自Mina的API文档):
void exceptionCaught(IoSession session, Throwable cause) |
void messageReceived(IoSession session, Object message) |
void messageSent(IoSession session, Object message) |
void sessionClosed(IoSession session) |
void sessionCreated(IoSession session) |
void sessionIdle(IoSession session, IdleStatus status) |
void sessionOpened(IoSession session) |
前面我们提到IoService是负责底层通讯接入,而IoHandler是负责业务处理的。那么Mina架构图中的IoFilter作何用途呢?答案是我们想作何用途都可以。但是有一个用途却是必须的,那就是作为IoService和IoHandler之间的桥梁。IoHandler接口中最重要的一个方法是messageReceived,这个方法的第二个参数是一个Object型的消息,众所周知,Object是所有Java对象的基础,那到底谁来决定这个消息到底是什么类型呢?答案也就在这个IoFilter中。在我们的应用中,我们添加了一个IoFilter是new ProtocolCodecFilter(new TextLineCodecFactory()),这个过滤器的作用是将来自客户端输入的信息转换成一行行的文本后传递给IoHandler,因此我们可以在messageReceived中直接将msg对象强制转换成String对象。
而如果我们不提供任何过滤器的话,那么在messageReceived方法中的第二个参数类型就是一个byte的缓冲区,对应的类是org.apache.mina.common.ByteBuffer。虽然你也可以将解析客户端信息放在IoHandler中来做,但这并不是推荐的做法,使原来清晰的模型又模糊起来,变得IoHandler不只是业务处理,还得充当协议解析的任务。
Mina自身带有一些常用的过滤器,例如LoggingFilter(日志记录)、BlackListFilter(黑名单过滤)、CompressionFilter(压缩)、SSLFilter(SSL加密)等。
在我们的项目中,主要的工作是在发送消息的部分,所以Mina框架的实现主要是围绕着IoHandler和IoSession进行展开。根据上面的讲解,在实际使用中,可以用下面的代码创建一个简单的用户发送消息的客户端。
SocketConnector connector = new SocketConnector();
IoFilter filter = new ProtocolCodecFilter(new TextLineCodecFactory());
connector.getFilterChain().addLast("audit", filter);
SocketAddress address = new InetSocketAddress(ip, port);
ConnectFuture future = connector.connect(address, newClientHandler());
future.join();
if (!future.isConnected()) {
logger.error("不能建立网络连接。" + address);
return null;
}
session = future.getSession();
这样便可以使用session进行消息发送,方法是使用write方法,创建一个WriteFuture就可以将信息发送出去了。
http://blog.sina.com.cn/s/blog_6712f9dd0100mor1.html
这篇关于Mina框架在项目中的使用(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!