`
sooxin
  • 浏览: 251431 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

转 Mina框架在项目中的使用

    博客分类:
  • J2EE
阅读更多

最近由于项目本身的需要,正在进行Mina框架的学习,并且将其整合到正在开发的系统中。下面将会根据实际的工作情况分享一些心得感受。

一、     项目需求:

我们正在开发的系统,现在主要分为两个部分,正两个部分之间需要使用TCP Socket进行网络通讯。具体开发的难点是发送消息的部分。由于需要考虑到每次创建连接时造成的系统开销,所以使用的连接方式必须是长连接,就是保存连接,不能断开。而且在连接的另一端发生当机的情况下能够及时回复,不会就此丢掉和这一端的通讯。在连接发送消息后,能够判定另一端无法及时收到消息的情况,并且做出正确处理。

综上所述,能够整理出如下三条需求:

l  两端的连接通讯必须是长连接,不能每次重新建立。

l  在连接断开的情况下能够及时处理,并能有效恢复。

l  发送数据需要有超时机制。

我们这一阶段的Mina框架的使用便是围绕着这三条需求展开的。

二、             Mina框架相关知识简介:

在正式开始Mina框架的实际应用前,先简单介绍一些Mina的基本知识,以便于下面的实用场景分析。中间会穿插架构图和示例代码。

在介绍架构之前先认识几个接口:

IoAccepter 相当于网络应用程序中的服务器端

IoConnector 相当于客户端

IoSession 当前客户端到服务器端的一个连接实例

IoHandler 业务处理逻辑

IoFilter 过滤器用于悬接通讯层接口与业务层接口

然后可以看一下Mina的架构图,如图2-1Mina框架图所示。

在图中的模块链中,IoService便是应用程序的入口,相当于基本接口中的IoAccepterIoAccepter便是IoService的一个扩展接口。IoService接口可以用来添加多个IoFilter,这些IoFilter符合责任链模式并由IoProcessor线程负责调用。而IoAccepterioService接口的基础上还提供绑定某个通讯端口以及取消绑定的接口。在日常应用中,我们可以这样使用IoAccepter

IoAcceptor acceptor = new SocketAcceptor();

相当于我们使用了 Socket 通讯方式作为服务的接入,当前版本的 Mina 还提供了除SocketAccepter外的基于数据报文通讯的DatagramAccepter以及基于管道通讯的VmPipeAccepter。另外还包括串口通讯接入方式,目前基于串口通讯的接入方式已经在最新测试版的MINA中提供。我们也可以自行实现IoService接口来使用自己的通讯方式。

而在上图中最右端也就是IoHandler,这便是业务处理模块。我们的项目大部分的工作也就是在这个接口的实现类中完成。在业务处理类中不需要去关心实际的通讯细节,只管处理客户端传输过来的信息即可。编写Handler类就是使用Mina开发网络应用程序的重心所在,相当于Mina已经帮你处理了所有的通讯方面的细节问题。为了简化Handler类,MINA提供了IoHandlerAdapter类,此类仅仅是实现了IoHandler接口,但并不做任何处理。

一个IoHandler接口中具有如下一些方法(摘自MinaAPI文档):

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) 
                   
当连接后打开时触发此方法,一般此方法与 sessionCreated 会被同时触发

前面我们提到IoService是负责底层通讯接入,而IoHandler是负责业务处理的。那么Mina架构图中的IoFilter作何用途呢?答案是我们想作何用途都可以。但是有一个用途却是必须的,那就是作为IoServiceIoHandler之间的桥梁。IoHandler接口中最重要的一个方法是messageReceived,这个方法的第二个参数是一个Object型的消息,众所周知,Object是所有Java对象的基础,那到底谁来决定这个消息到底是什么类型呢?答案也就在这个IoFilter中。在我们的应用中,我们添加了一个IoFilternew ProtocolCodecFilter(new TextLineCodecFactory()),这个过滤器的作用是将来自客户端输入的信息转换成一行行的文本后传递给IoHandler,因此我们可以在messageReceived中直接将msg对象强制转换成String对象。

而如果我们不提供任何过滤器的话,那么在messageReceived方法中的第二个参数类型就是一个byte的缓冲区,对应的类是org.apache.mina.common.ByteBuffer。虽然你也可以将解析客户端信息放在IoHandler中来做,但这并不是推荐的做法,使原来清晰的模型又模糊起来,变得IoHandler不只是业务处理,还得充当协议解析的任务。

Mina自身带有一些常用的过滤器,例如LoggingFilter(日志记录)、BlackListFilter(黑名单过滤)、CompressionFilter(压缩)、SSLFilterSSL加密)等。

在我们的项目中,主要的工作是在发送消息的部分,所以Mina框架的实现主要是围绕着IoHandlerIoSession进行展开。根据上面的讲解,在实际使用中,可以用下面的代码创建一个简单的用户发送消息的客户端。

            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, new ClientHandler());

            future.join();

            if (!future.isConnected()) {

                logger.error("不能建立网络连接。" + address);

                return null;

            }

            session = future.getSession();

这样便可以使用session进行消息发送,方法是使用write方法,创建一个WriteFuture就可以将信息发送出去了。下面将结合我们的三个网络通讯的需求,在实际项目中分析Mina框架的使用。

 

三、             实用场景分析:

首先是长连接的问题,为了避免每次重复创建连接,就要对连接进行管理。每一个连接在Mina中的就是通过session进行体现的,换言之,就是将session管理起来。所以,我们索性就把网络通讯的部分,与项目的其他部分进行隔离,实现一个网络通讯层,在其中统一管理session。然后在通讯层中实现一个静态MapKeyIP+PortValue就是对应的session。然后在每次需要进行连接的时候,从这个Map中通过IPPort获取对应的session。然后判断这个session是否被创建,或者是session是否被关闭。如果这个session有效,便直接进行使用。如果session无效,再重新创建这个session,然后放到Session Map中。如图3-1通讯层结构类图所示。

 

然后是连接断开和恢复的处理,在我们实现的Client Handler中,有一个可以被覆盖的方法,void exceptionCaught(IoSession session, Throwable cause)。这个方法在服务器端非正常当机的情况下可以捕获到异常,而且服务器端在线上环境下是不会进行主动连接断开的。所以异常情况便可以包括现有的连接断开情况。如果有这样的情况发生,就将这个session关闭到,然后再需要重新获取这个session的时候,便会判定这个session已经断开,这时会重新创建一个新的session,将Session Map中的元素覆盖掉。

最后是发送信息超时,这个是在每个session的写操作的时候处理,每个写操作在Mina框架中都是一个异步操作,本身程序是不会等待整个操作的结束的,因为这是根据性能上的考虑。但是如果我们需要知道发送消息是否超时,便可以在前期的简单实现过程中使用这种方式。首先为session设定一个写操作的超时时间,我们设置5秒钟,然后在每个写操作之后都使用join方法,等待异步操作结束。最后便可以判断写操作是否成功进行,这样就可以处理发送消息超时的问题。可以用下面的代码表示。

    public void sessionCreated(IoSession session) throws Exception {

        super.sessionCreated(session);

        session.setWriteTimeout(5);

        if (session.getTransportType() == TransportType.SOCKET) {

            ((SocketSessionConfig) session.getConfig()).setKeepAlive(true);

        }

}

这个是在session被创建的时候,同时还有一项设置是,将Session的连接模式设置成长连接。这样连接就不会有超时中断的现象。

    public static boolean setMessage(String ip, int port, String message) {

        IoSession session = getSession(ip, port);

        if (session != null) {

            WriteFuture wf = session.write(message);

            wf.join();

            if (wf.isWritten()) {

                return true;

            }

        }

        return false;

}

这个是发送消息的部分,在发送消息后,判断消息是否成功发送,这样就可以做到处理发送消息超时的问题。

四、             后期优化:

在项目中,现在的Mina框架实现形式还是有许多需要改进,并优化的部分。比如说超时的处理和多线程的问题。

在发送超时的问题上,如果每次发送消息后,都进行异步操作的等待,那么在数据量十分庞大的情况下便会产生效率问题。根据Mina框架中存在的Future模式,可以使用listener来处理是否发送消息超时。可以在Session中添加专门用来处理消息发送超时的listener,然后在需要发送的消息上标注是否超时,如果超时进行重发,或者是其他操作。这样可以大大加快发送消息的速度,但是对于程序的复杂性,便会有很大的提升。由于现在正处在项目的初期是现阶段,可以不需要考虑这种复杂的模式。但是可以最为后期优化的内容。

至于多线程的问题,由于Mina框架本身就拥有线程池的功能,所以它是可以做到多线程的消息发送的。可是这需要消息缓冲区的配合,而且会造成现有系统整合上的冲突,所以,也不在目前情况的考虑范围内。但是,后期可以考虑实现这方面的功能。

PS: mina是日语,意思是大家。作者使用这个名字,可能是希望大家都来使用这个框架,并且通过这个网络框架,将大家联系在一起。

分享到:
评论
4 楼 sooxin 2012-01-10  
mina 采用一种NIO通信,底层的连接机制没有具体研究过,但经过自己本人实践测试,在游戏过程中如果拔掉网线,在短几秒内插上,可以继续通信游戏。如果你想及时判断掉线,那就有加心跳机制。但心跳机制也不一定很及时,也需要看mina的一些相关设置。这里可以考虑使用red5,他是基于mina的通信,各方面功能也完善。
3 楼 gigi_ly180 2011-02-18  
和2楼一样的问题,目前没有解决方法,除非搞个类似心跳机制……,不知都怎么做?
2 楼 wxpuc123 2010-12-16  
你好最近有一个项目,就是当出现网络故障的时候,比如把网线拔掉后,服务器端的连接没有中断。请问这个要怎么处理,我怎么判断服务器跟客户端处于一直连接状态呢??
1 楼 wangjia 2010-11-02  
您好,最近我也学习了这个框架的使用,但是一直不解的是MINA作为一个单独的服务在运行的时候是如何与现有项目整合到一起的?如何做到项目启动,mina的服务也随之启动?在mina的消息接收方法如何调用系统中spring service方法呢?与正常struts的调用是一样的吗?

相关推荐

    mina2框架+项目实例教程

    它提供了一个抽象的、事件驱动的异步API,使Java NIO在各种传输协议(如TCP/IP,UDP/IP协议等)下快速高效开发。 Apache Mina也称为:  NIO框架  客户端/服务端框架(典型的C/S架构)  网络套接字(networking...

    java-mina通信框架详解.docx

    并根据本人在工程项目中使用的代码,详细讲解了服务器端是客户端实现。实现了json格式的通信、以及文件的上传于下载等功能。图文并茂,以开发者的角度来展示知识的结构。希望对大家有所帮助!!

    mina框架中socket使用,有服务端和客户端。

    mina框架中socket使用,有服务端和客户端。这是比较完整的项目。希望能给后人点参考

    Mina框架项目

    项目名称为MinaTest,由java搭建而成的Mina基本框架的JavaProject项目,下载后直接用eclipse导入工程,如果报错,注意Jdk环境设置为1.6或以上,要配合使用mina的基本包和slf4j包等jar包,即可完美解决报错,非常基本...

    MINA框架源码

    从github上下载的mina框架源码 Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便 apache mina apache mina...

    Apache MINA框架所用的jar包

    Java中使用Apache MINA框架所用的jar包,将其导入到项目中即可

    Mina+Struts2+Spring4+Mybatis3组合

    该项目是本人真实项目中使用到的mina + spring+struts2 + mybatis框架,里面有详细的注释说明,以及一个完整的接收消息、入库、返回例子。对需要真实项目开发的人员来说,可以直接使用。 另外,如果需要更加详细的...

    android socket 编程 MINA 框架相关jar包

    android中使用MINA框架所用的jar包,将其导入到项目中即可

    MINA框架中文API(个人翻译)

    最近一个项目用到了MINA框架,自己翻译的API,里面有一些自己写的例子。

    微信小程序 Web MINA框架下载.rar

    一个开放的、运行微信小程序的Web MINA框架,在源代码的node_modules文件夹下,集成了MINA框架下的许多微信开发类库,在微信开发时助你一臂之力,测试项目比较简单,有兴趣的可下载源码。

    mina框架中socket应用的简单小项目,包含了所需jar

    mina框架中socket应用的简单小项目,包含了所需jar

    高性能Java网络框架 MINA

    高性能Java网络框架 MINA

    mina项目示例

    该项目是采用mina框架做的客户端与服务端通信 mina框架相比socket通信有许多好处还是非常不错的 这个项目示例比较经典

    MINA框架 多人聊天的技术原型 包含slf4j和Log4j配置

    这是MINA实现的多人聊天的技术原型 采用MAVEN做配置管理, 项目需要jar里面也有,是从Maven的repository中拔下来的 供大家参考

    Mina状态机介绍和实例

    通过使用MINA框架可以可以省下处理底层I/O和线程并发等复杂工作,开发人员能够把更多的精力投入到业务设计和开发当中。MINA框架的应用比较广泛,应用的开源项目有Apache Directory、AsyncWeb、Apache Qpid、QuickFIX...

    mina高性能Java网络框架 v2.1.3

    当前发行的MINA版本支持基于Java NIO技术的TCP/UDP应用程序开发、串口通讯程序(只在最新的预览版中提供),MINA所支持的功能也在进一步的扩展中。 Apache MINA是一个网络应用程序框架,可帮助用户轻松开发高性能和...

    使用MINA进行UDP通信实现数据导入

    有丰富的MINA通信软件开发经验,现在已经有成熟的底层框架(结合了反射、DynaBean、Spring等多种技术),可以实现程序自动对上位机和下位机之间的通信协议进行解析,并在国网公司智能电网的大型项目中使用。...

    freemina,一个免费的mina兼容框架,可在浏览器或webview中运行。Mina是微信应用的框架,微信应用是微信应用的框架。21488页.zip

    freemina,一个免费的mina兼容框架,可在浏览器或webview中运行。Mina是微信应用的框架,微信应用是微信应用的框架。21488页.zip

    微信小程序开发框架MINA分析

    MINA框架中有四种类型的文件: .js文件 基于JavaScript的逻辑层框架 .wxml 视图层文件,是MINA设计的一套标签语言 .wxss 样式文件,用于描述WXML的组件样式 .json 文件,配置文件,用于单个页面的配置和整个项目的...

    Apache Mina核心jar包:mina-core-2.0.7

    Apache MINA是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。 当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版...

Global site tag (gtag.js) - Google Analytics