`
sooxin
  • 浏览: 257235 次
  • 性别: 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的调用是一样的吗?

相关推荐

    Java springboot 整合mina 框架,nio通讯基础教程,mina框架基础教程.zip

    总结来说,本教程将引导你从理论到实践,掌握Java NIO的基本原理,理解Mina框架的使用,以及如何在SpringBoot环境中整合Mina实现高效的网络通信。通过这些知识的学习,你将具备开发高并发、高性能网络应用的能力。

    mina框架资源包

    在Mina框架中,SLF4J被用作日志接口,使得开发者可以根据实际需求选择合适的日志实现,便于调试和监控程序运行状态。 结合这三个文件,开发者可以快速搭建一个基于Mina的即时通讯服务器。首先,将`apache-mina-...

    Mina框架+常用JAR包

    1. **引入依赖**:在项目中添加Mina框架所需的JAR包,如果是Maven项目,可以通过配置pom.xml文件来引入依赖。 2. **配置服务器**:定义服务端的监听端口,创建IoAcceptor对象,并设置相应的协议处理器和过滤器链。 3...

    MiNA框架新人指导

    在MiNA框架中,服务端的搭建相对简单,可以通过以下几个步骤实现: - **创建IoAcceptor对象**:这是MiNA框架中的核心组件之一,用于接收客户端的连接请求。 - **配置过滤器链**:定义一系列过滤器来处理数据流,...

    mina框架的使用

    在描述中提到的"mina简单事例"博客文章,作者可能详细解释了如何使用MINA框架创建一个简单的网络应用。通常,这样的示例会包含以下步骤: 1. **设置项目**: 创建一个新的Java项目,并引入MINA的依赖库。 2. **创建...

    java mina框架全套

    Java Mina框架是一款高度可扩展且高性能的网络应用开发框架,专为开发网络服务和协议处理应用程序而设计。...在实际项目中,结合Mina与其他开源库如Spring、Hibernate等,可以构建出更加强大的企业级应用。

    Apache MINA框架相关资料

    通过这些资料的学习,开发者不仅可以掌握MINA的基本使用,还能深入了解其设计思想和实现方式,同时还能学习到如何在实际项目中利用Spring框架的优势,提升MINA应用的开发效率和质量。对于任何希望涉足网络服务开发,...

    mina框架开发完整架包下载!

    2. **Mina Examples**:示例代码可以帮助开发者理解如何使用Mina框架进行实际开发。这些例子涵盖了各种应用场景,如简单的TCP服务器、聊天应用等。 3. **Mina Dependencies**:可能包括Mina框架依赖的其他库,如...

    java-mina通信框架详解.docx

    在项目中,除了Mina的核心包,可能还需要日志处理相关的依赖。 在Mina中,IoService接口提供了添加和移除监听器的能力,允许开发者监听IoService的生命周期事件,如创建、活动、失效等,增强了对服务的控制能力。...

    Android Mina框架使用

    下面将详细介绍Mina框架在Android中的应用及其核心概念。 1. **Mina框架基础** Mina源于Java平台,但在Android上同样适用。它提供了事件驱动的非阻塞I/O模型,提高了网络通信的效率。Mina的核心组件包括Acceptor...

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

    mina框架是Apache组织开发的一个网络通信框架,...通过这个项目,开发者不仅可以学习到MINA框架的基础使用,还能了解网络编程中的服务端与客户端交互原理,以及如何利用MINA提供的工具来构建高效、稳定的网络应用程序。

    mina框架的demo 入门,开发

    在Java项目中,你可以通过Maven或Gradle来管理依赖。例如,在Maven的`pom.xml`文件中添加如下依赖: ```xml <groupId>org.apache.mina <artifactId>mina-core <version>2.0.27 ``` 接下来,我们将构建一个简单...

    mina2框架+项目实例教程

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

    mina框架的jar包

    当项目中同时存在SLF4J和Java内置日志时,这个绑定会让SLF4J使用Java内置日志进行日志记录。 `slf4j-log4j12-1.6.1.jar`则是SLF4J与Log4j的绑定实现,它使得SLF4J能够使用Log4j作为日志系统。Log4j是一款功能强大且...

    Mina 框架研究与实现

    这一框架已被广泛应用于多个领域,如Red5项目中的RTMP协议实现、SubEtha.SMTP项目中的SMTP协议、Apache Qpid项目中的AMQP协议,以及Openfire项目中的XMPP协议等。这些实例充分展示了Mina框架在不同场景下的强大适用...

    高性能网络架构Mina框架 下载

    ### 高性能网络架构Mina框架...综上所述,Mina框架作为一款高性能的网络通信框架,在Java NIO环境下展现出了卓越的性能和稳定性。无论是对于初学者还是有经验的开发者而言,深入学习和掌握Mina都将是一笔宝贵的财富。

    Android平台MINA框架使用详细解析

    在这个项目中,可能包含了配置MINA、处理网络连接、数据交换以及处理乱码和连接稳定性等各个方面的问题。通过分析和运行这个项目,开发者可以深入理解MINA在Android上的实际应用,并学习如何解决实际开发中遇到的...

    基于Android开发MINA框架使用详解

    本教程将深入探讨如何在Android项目中集成MINA框架,以及如何解决在实际开发中可能遇到的问题,如中文乱码和消息接收不全等问题。 1. **MINA框架基础** - MINA的核心是其异步事件驱动模型,它允许开发者通过回调...

    mina框架demo

    标题中的"mina框架demo"是指使用MINA框架创建的一个示例项目,通常这个项目会包含一系列的代码和配置,演示了如何利用MINA来构建网络应用程序。这样的示例对于初学者来说是非常有价值的,因为它可以帮助理解MINA的...

    MINA框架使用jar包(Android)

    在Android项目中集成这些jar包时,通常会将它们添加到项目的libs目录下,并在项目的build.gradle文件中声明为依赖。在Android Studio中,可以使用`implementation files('libs/xxx.jar')`来添加本地库。 使用MINA...

Global site tag (gtag.js) - Google Analytics