




已阅读5页,还剩39页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
滨州学院计算机科学与技术系seesky译制第一章开始 在这一章中,我们将给你什么是MINA、NIO的第一感觉,以及为什么我们在NIO上构建框架。我们还展示了如何运行一个基于MINA的非常简单的程序例子。1、NIO综述 NIO APIs在Java 1.4中被给出,如今它已经在在大量的程序中被使用了。NIO APIs允许非阻塞IO操作。 注意:首先,知道MINA是在NIO 1的基础上开发的是很重要的,如今在Java 7中一个新版本的NIO-2已经被设计出来,但是我们还没有从这个版本所带有的特性中获益。 注意:知道N在NIO中的意思是New也是重要的,但是我们将在很多地方使用非阻塞(Non-Blocking)这个术语。NIO-2需要被看为New New I/O java.nio.*包包含以下关键结构 Buffers数据容器 Chartsetsbytes和Unicode之间的翻译容器 Channels代表I/O操作的连接实体 Selectors提供可选择的多路复用非阻塞IO Regexps提供一些操作正则表达式的工具 我们将集中关注MINA框架的Channels、Selectors以及Buffers部分,其它部分我们将对用户进行隐藏。 本手册将集中关注在这些内部组件上构建我们所需要的系统。NIO vs BIO 知道BIO和Clocking IO这两种APIs之间的不同是很重要的,在阻塞模型中依赖普通的sockets链接:当你读、写或者在socket上做任何操作的时候,被调用的操作将会阻塞调用者,知道操作完成。 在一些例子中,关键是能够调用操作,并期望被调用的操作在操作完成之后能够通知调用者:这使得调用者在平均的运行时间里可以做更多的事情。 这也就是NIO的优点,当你有很多的socket链接时,NIO能帮你更好的处理它们:你不需要为每一个链接创建指定的进程,你只需要使用少量的进程来做同样的事情。 如果你想获得有关于NIO的更多信息,网上有很多不错的文章,还有几本书讲述了有关NIO的问题。2、为什么开发MINA 编写网络程序被看做是繁重的底层开发。它一个开发者不经常学习和知晓的区域,要么是因为很久之前在学校里学过但是现在已经忘了,或者是因为复杂的网络层总是被高层隐藏,总之你没有深入学习过它。 另外当涉及到异步IO的时候,一个额外的发杂层又参杂了进来:time。 BIO(Blocking IO)和NIO(Non-Blocking IO)之间的最大的区别是,在BIO中,你发送一个请求,然后需要一直等待直到你获得答复。在服务器端,这意味着一个进程将会与一个对内连接相联系,所以你不得不处理复杂的多路链接。在NIO中,另一方面,你需要解决非阻塞系统的同步工作,这就意味当一些事情发生之后,你的程序将被唤醒。在NIO中,你不需要调用和等待结果,你发送完命令之后,之后当恢复准备好了你将获得通知。框架的需求 考虑到这些不同,事实上许多的程序都期待在调用网络层的时候有一个阻塞模式,而最好的解决方法就是编写一个模拟阻塞的框架来隐藏这些不同。这就是为什么需要MINA。 但是MINA可以做更多。它为使用TCP、UDP和其他机制进行通信提供统一的接口。当你只考虑TCP和UDP的时候,一个是有连接的(TCP),而另外一个是无连接的(UDP)。MINA掩饰这些不同,使你能够专注于你的程序的两个重要部分:程序的编码以及协议的编码和解码。 MINA不但可以处理TCP和UDP,它还通过VmpPipe或APR为串口通信(RSC232)提供了一个高层接口。 最后但不是最终的,MINA被特别的设计为能够在客户端和服务器端都能运行的网络框架。 编写一个关键是能够扩展的系统,同时在性能和内存使用方面能够符合服务器的要求:这就是MINA所擅长的,它使得构建你自己的服务器变得简单。什么时候使用MINA? 这是一个有趣的问题!MINA在一些情况下并不是最好的选择。当你想要使用MINA的时候有几个元素需要考虑。让我们来看看: 当你没有特定的性能环境的时候它是易用的,这个时候MINA是一个很好的选择因为它让你更简单的构建一个服务器或客户端,而不用在BIO和NIO的上层重复编写处理代码和处理各种参数。你甚至能够用简单地10行代码完成你的服务器,而且可以避免更少的问题。 一定数量的用户连接BIO是比NIO快的。不同的是大约30%支持BIO。这对于拥有几千条用户连接的系统是正确的,但是在一定程度上,BIO已经停止扩展了:你不能用一个用户一个进程的方式处理百万级的用户连接!而NIO可以。另一方面你在MINA部分所花费的时间在你整个程序的编码过程中也许并不重要。在一定程度上,编写一个更快的网络层也许并没有什么价值,因为性能基本得不到提升。 在全世界有数万的程序在使用MINA,这可以证明MINA很有用。有很多的Apache项目基于MINA,它们工作的都很好。这也保证了你不用花费数小时的时间来解决你自己的网络层实现中所遇到的奇怪问题了。 MINA当前支持的已存在协议有:HTTP、XML、TCP、LDAP、DHCP、NTP、DNS、XMPP、SSH、FTP在一定程度上,MINA不只是一个NIO的网络框架,它还是一个带有许多协议实现的网络框架。MINA的一个未来发展是成为一个你能够使用的各种存在协议的集合。产品特点 MINA是一个简单地同时也是全功能的网络程序开发框架,它提供了以下功能: 为各种传输方式提供了同一个API:o 基于NIO的TCP/IP & UDP/IPo 基于RXTX的串口通信(RS232)o In-VM pipe 通信o 你可以在它上边实现你自己的通信! 作为扩展的过滤器接口;类似于Servlet的过滤器 底层和高层API:o 底层:使用ByteBufferso 高层:使用用户定义的信息类和编码 可定制的进程模型:o 单线程o 线程池o 多个线程池(SEDA) Out-of-the-box SSL.TLS.StartTLS 支持使用Java 5 SSLEngine 过载保护和流量节流 模拟对象的单元测试 JMX可管理性 基于流的IO操作:StreamIoHandler 与一些知名的容器集成,例如PicoContainer和Spring 从Netty的平滑迁移,MINA的祖先第一步 我们将运行一个MINA包提供的示例代码为你展示如何简单地使用MINA。 你所要做的第一件事就是在你的程序中使用MINA之前配置你的环境。我们将描述你需要安装什么和如何运行MINA程序。没什么技巧,只是一个MINA的测试下载 首先你需要从现在站点现在最新的MINA发布包。最好下载最新版,除非你有很好的理由不这样做 一般而言,如果你想使用MINA构建你自己的项目,你不需要下载什么东西,你只需要将一个MINA库包含到你的项目中就可以了:你只需要告诉你的IDE你要使用MINA的jar包就可以了。MINA库中有什么 在你下载完成之后,提取tar.gz或zip文档中的文件到本地目录。压缩文档中包含了以下内容。 在UNIX系统中: 在apache-mina-2.0.7目录中,你能够得到:内容详情 dist包含MINA的jar包 doce包含API文档和代码引用文件 lib包含MINA要用到的所有的jar库 除此之外,根目录还包含license文件和其他几个注意文件运行你的第一个MINA程序 好的,你已经下载了最新的MINA,让我们来运行MINA中附带的示例程序。 把以下包加入classpath mina-core-2.0.7.jar mina-example-2.0.7.jar slf4j-api-1.6.6.jar slf4j-log4j12-1.6.6.jar log4j-1.2.17.jar在命令行中输入以下命令: 这条指令将启动服务器。现在使用telnet连接服务器看有什么结果。 输入如下telnet指令: 现在你已经运行了第一个MINA程序。请尝试MINA中附带的其他示例程序。概要 在这一章中,我们看到了基础的MINA程序结构,它对于客户端和服务器都适用。我们还涉及到了简单地TCP服务器/客户端的实现,还有UDP服务器和客户端。 在接下来的一章中,我们将会讨论MINA的核心结构和一些更高级的话题。第二章基础 在第一章中,我们简单地了解了一下MINA。在这一章中我们将会看到服务器/客户端的结构和一些它们的细节。 我们将会展示一些简单地基于TCP和UDP的服务器和客户端示例。基于MINA的应用程序结构 我们也可以这样问:“一个基于MINA的程序看起来是什么样子的?”在这一章中,让我们来看一看基于MINA的程序的结构。我们试图从MINA演示中搜集信息。鸟瞰图: 在这我们看到MINA是你的程序(客户端或服务器)与网络层之间的粘合剂,而程序的底层可以是基于TCP、UDP、in-VM连接,甚至是RS-232C串口协议的连接。 你只需要在MINA的上层构建你的应用而不需要处理复杂的网络层问题。 让我们更深入细节一些。下边的图片展示了MINA的组成,并写出了每部分做功能: 很明显,基于MINA的程序分为三层: I/O服务实际执行I/O操作 I/O过滤器链对所需的数据就够进行过滤/翻译,反之亦然 I/O处理这里包含着真正的业务逻辑 所以,为了构建一个基于MINA的程序,你需要: 创建I/O服务从已有服务器选择一个或者创建你自己的 创建过滤器链选择已经存在的过滤器或者是定义用户转换请求/回复的过滤器 创建处理器编写业务逻辑,处理不同的信息 你可以通过阅读以下两个文件更深入的了解这方面的内容: 服务器结构 客户端结构 当然,MINA提供了比这更多的功能,你还需要注意其他的一些方面,像信息的编码/解码,网络配置的扩展等我们将在下一张进一步讨论这些问题。服务器结构 在上一小节我们已经展示了MINA程序的结构。接下来让我们看一下服务器的结构。基本上,一个服务器要在特定的端口上监听客户端的请求,处理这些请求并作出回复。同时它需要创建和处理与每一个客户端之间的连接(不管你使用的是TCP还是UDP协议),这些将在第四章中有更详细的解说。 IOAcceptor监听来自网络的连接和数据包 对于一个新的连接,一个对话将会被建立,同时随后来自于这个IP地址和端口的通信都将通过这个回话进行处理 对一个会话的所有数据包,都会穿过如图所示的过滤器链。过滤器可以被用来修改数据包的内容(例如转换对象、添加或者删除信息等)。这对于为高层对象转化进出的比特数据,以及对数据的编码和解码是特别有用的。 最后数据包或转化的对象将被放在IOHandler中。IOHandler在整个业务逻辑过程中都可以被使用。会话的创建 无论什么时候一个客户端连接到MINA服务器,我们都会创建一个会话并把固定的数据保存在里边。及时协议不是面向连接的,这个会话也会被创建。下边的架构图展示了MINA如何处理对内的连接:图挂了!对内信息的处理 我们现在解释了MINA如何处理队内的信息。 假设对话已经被建立,当一些新的信息到来的时候,它将会导致一个选择器被唤醒。简单地TCP服务器快速开始手册此手册将会带你构建一个基础的MINA程序。此手册将会构建一个时间服务器。本手册需要以下预备知识: MINA 2.0.7 核心 JDK 1.5 或更高版本 SLF4 1.3.0 或更高版本o Log4J 1.2users:slf4j-api.jar,slf4j-log4j12.jar, andLog4J1.2.xo Log4J 1.3users:slf4j-api.jar,slf4j-log4j13.jar, andLog4J1.3.xo java.util.loggingusers:slf4j-api.jarandslf4j-jdk14.jaro 重要:请确保对你的日志框架使用了正确的slf4j-*.jar版本。例如,slf4j-log4j12.jar和log4j-1.3.x.jar不能同时使用,将会出现问题。 我已经在Window 2000系统和Linux系统上测试了这个程序。如果你再运行这个程序的时候有什么问题,请不要犹豫,联系我们或告诉其他的开发者。并且,本手册已经尽量独立于特定的开发环境(IDE、编辑器等)。这个手册将在你熟悉的开发环境中运行的很好。这个程序的编译命令和执行命令已经被剔除的很简洁。如果你需要学习如何编译和运行程序,请查看其他java手册。编写MINA时间服务器 我们将要建立一个叫做MinaTimeServer.java的文件。起始代码如下所示:public class MinaTimeServer public static void main(String args) / code will go here next 代码就是如此。我们简单地定义了一个用于启动程序的main方法。接下来,我们将会添加用于代码来弥补我们的服务器。首先,我们需要一个用来监听外来连接的端口。这个程序将基于TCP/IP,我们将向程序中添加一个SocketAcceptor。 通过这个NioSocketAcceptor类,我们可以继续前进来定义一个处理类同时将NioSocketAcceptor绑定到一个端口上。 接下来我们给配置添加一个过滤器。这个过滤器将会把所有的信息写入日志中,例如新session的创建、信息的获取、信息的发送、session的关闭。下一个过滤器是ProtocolCodecFilter。这个过滤器将会把二进制或符合协议规范的数据翻译成消息对象,反之亦然。我们使用一个已经存在的TextLine工厂,它将会为你处理关于text的信息(这样你就不用自己写代码了)。 接下来,我们将会定义一个处理过程,它将会被用来接受客户端的连接,并回复当前时间。这个处理器必须是一个实现了IoHandler接口的类。对于所有使用MINA的程序来说,这个处理器将是最主要的程序,它将为接入的所有客户端提供服务。对于本手册来说,我们将继承IoHandlerAdapter类。这个类遵循适配器模式,它简化了大量为满足实现IoHandler接口的类所需要的代码。 现在我们将会添加NioSocketAcceptor配置。这将使得我们可以对socket进行特定的设置,此socket将被用来接受客户端的连接。 在MinaTimeServer类中有两个新行。这些方法设置了IoHandler的设置,输入缓冲区大小和会话的空闲性能。缓冲区的尺寸将被指定,它将通知潜在的操作系统应该为输入的数据分配多少空间。第二行指定多长时间监测空闲会话。在调用setidleTime的时候,第一个参数定义了当检测到会话空闲的时候要做什么,第二个参数定义了判定会话为空闲的时长。 处理器类的代码如下所示: 在这个类中使用的方法有exceptionCaught、messageReceived和sessionidle。exceptionCaught总会在一个处理器类中被实现,它将处理远程连接过程中产生的异常。如果这个方法没有被定义,异常将不能得到正确的处理。 exceptionCaught方法将简单地输出错误堆栈的信息,并关闭会话。对于大多数程序来说,这将是基本的实践,除非处理器类能从异常中恢复过来。 messageReceived方法将接受来自客户端的数据同时将当前时间写回给客户端。当从客户端接收到的信息是“quit”,则会话将被关闭。这个方法将向客户端打印当前时间。依赖你所使用的协议编码器,在第二个方法中传输的对象将会不同,它将会是你在session.write(Object)方法中传输的对象。如果你没有指定协议编码器,你将接收到一个IoBuffer对象,并回复一个IoBuffer对象。 sessionidle方法将会在会话被确定为空闲后执行,这段空闲时间我们已经使用acceptor.getSessionConfig().setidleTime(idleStatus.BOTH_IDLE, 10)中进行了设置。 接下来所要做的就是定义一个socket地址,用于服务器的监听,然后启动服务器。代码如下:测试时间服务器 接下来,我们可以继续并编译这个程序。一旦你编译完这个程序,就可以启动它来测试将会发生什么。最简单的测试方式就是启动这个服务器,并用telnet连接它:简单地TCP客户端 我们已经看过了客户端的结构。接下来让我们看一下一个客户端的实现。 我们用一个Sumup Client作为参考实现。 我们将删除样板代码并把注意力集中在一些重要的结构上,以下是客户端的代码:为了构建一个客户端,我们需要做下边的事情: 创建一个Connector 创建一个过滤器链 创建一个IOHandler并添加Connector 绑定到服务器 下面让我们详细的说明每一步。创建一个Connector 在这我们创建了一个NIO socket连接。创建一个过滤器链 我们为Connector将过滤器添加到过滤器链中。这里我们将ProtocolCodec添加到了过滤器链中。创建一个IOHandler 在这里我们创建了一个ClientSessionHandler的示例,并将其配置到Connector上。绑定服务器 这是很重要的部分。我们连接远程服务器。至此,连接是个异步任务,我们使用ConnectFuture类确定什么时候连接完成。一旦连接完成,我们将得到连接IoSession。为了向服务器发送信息,我们需要向这个session中写数据。所有来自服务器的回复和信息将会穿过过滤器链并最终在IoHandler中得到处理。简单地UDP服务器 我们来看看org.apache.mima.example.udp包中的代码。为了让示例简单,我们只简述MINA的内容。 为了构造服务器,我们需要做下边的事情: 创建一个数据包Socket用来监听来自客户端的请求(看MemoryMonitor.java) 创建一个IoHandler来处理MINA框架的事件(看MemoryMonitorHandler.java) 以下是一个小片段: 在这,我们创建了一个NioDatagramAcceptor来监听来自客户端的请求,同时设置IoHandler。变量“PORT”只是一个int型数据。下一步是为DtagramAcceptor添加要使用的日志过滤器。用LoggingFilter查看MINA是如何活动的是一种很好的方法。它在不同的阶段产生日志文档,提供了MINA如何工作的例证。 接下来让我们插入一些UDP传输的特殊代码。我们将会设置这个acceptor使用这个地址: 当然我们需要做的最后的事情就是调用bind()函数。IoHandler的实现 有三个主要事件是我们的服务器实现所感兴趣的: 会话创建 信息接收 会话关闭 让我们分别看看它们的详情。会话创建事件 在会话的创建事件中,我们只是调用了addClient()函数,它在UI上添加了一个标签。信息接收事件 在信息接收事件中,我们只是将接收到的信息全部送入message中。程序能够使用这个函数发送回复、处理信息并把回复写入会话中。会话关闭事件在会话关闭事件中,我们只是简单地将客户端标签从UI上移除了。简单地UDP客户端 让我们看看UDP客户端的代码。 为了实现这个客户端,我们需要做下边的事情: 为服务器创建Socket和Connect 设置IoHandler 收集空闲内存 向服务器发送数据 我们先来看MemMonClient.java,它在org.apache.mina.example.udp.clent包中。开始的一段代码直截了当: 在这我们创建了一个NioDatagramConnector,为服务器配置了handler和connect。我遇到的一个问题是你必须在InetSocketAddress对象中设置主机或者别的什么工作。这个例子是在Windows XP上进行测试的,所以一些工作在其他地方可能会不同。接下来我们需要等待确认客户端连接到了服务器。一旦连接成功,我们可以开始等待来自服务器的数据。代码如下: 在这里我们为ConnectFuture对象添加了一个监听器,当我们获得一个客户端已经连接的回调时,我们就开始写数据。向服务器写入的数据通过调用sendData函数来处理。这个方法的代码如下: 这个方法每30秒就会将大量空闲内存写给服务器。在这里我们可以看到,我们分配了一个足够大的IoBuffer用来保存一个长变量然后把大量的空闲内存放入这个buffer中。随后这个buffer将会被遍历并写给服务器。 我们的UDP客户端实现就完成了。概述 在这一章中,我们看了基于MINA的程序的结构,包括客户端和服务器。同时我们涉及到了简单TCP服务器客户端和UDP服务器客户端的实现。 在接下来的一章中,我们将会讨论MINA核心结构和高级主题。第三章IoService MINA IoService它是所有IO服务的基础类,包括服务器端和客户端。 它将处理所有与你的程序之间的互动,发送和接收信息,管理会话,连接等。 它是一个接口,它在服务器端有IoAcceptor实现,在客户端有IoConnector的实现。 我们将会在接下来的章节中介绍这些接口:IoService介绍 IoService在MINA中提供了基本的I/O服务和I/O会话管理服务。它是MINA结构中最重要的部分。IoService的实现类和子接口是绝大多数底层I/O操作进行的地方。IoService思维导图 让我们来看看IoService和她的实现类AbstractIoService类的职责。让我们用一种稍微不同的方式,先使用思维导图然后再跳进内部的工作过程。思维导图是由XMind创建的。职责 在给出的图像中可以看出,IoService有以下职责: 会话管理:创建和删除会话,检测空闲情况 过滤器链管理:处理过滤器链,允许用户在工作过程中修改过滤器链 处理调用:当收到信息的时候调用处理器,等 统计管理:更新信息发送、bytes和其他数据的发送数量 监听器管理:管理用户可以设置的监听器 连接管理:在两个方向处理数据的传输 这所有的方面在接下来的章节中将被描述。接口细节 IoService是所有IoConnector和IoAcceptor所提供的I/O服务和I/O对话管理的基础接口。这个接口包含了所有用于I/O相关操作的函数。 让我们来深入的看一下这个接口中的各种函数 getTransportMetadata() addListener() removeListener() isDisposing() isDisposed() dispose() getHandler() setHandler() getManagedSessions() getManagedSessionCount() getSessionConfig() getFilterChainBuilder() setFilterChainBuilder() getFilterChain() isActive() getActivationTime() broadcast() setSessionDataStructureFactory() getScheduledWriteBytes() getScheduledWriteMessages() getStatistics()getTransportMetadata() 这个方法返回IoAcceptor或IoConnector运行过程中的传输元数据。典型细节包括名字(nio、apr、rxtx),连接类型(无连接/有连接)等。addListener 允许添加一个用于监听与IoService有关的事件的指定监听器。removeListener 移除绑定在这个IoService的指定的IoServiceListener。isDisposing 这个方法将告知这个service当前正在被处理。由于它会花费一些时间,所以获得service的当前状态是很有用的。isDisposed 这个方法将告知这个service已经被处理过了。只有当service申请的所有资源全部被释放的时候,它才被认为处理过了。dispose 这个方法将释放所有service所申请的资源。由于它会花费一些时间,所以用户需要使用isDisposing()和isDisposed()来检测当前的service是否已经被处理完成了。 当你关闭一个service的时候一定要调用dispose()。getHandler 返回service所申请的IoHandler。setHandler 设置用于处理所有事件的IoHandler。这个handler将包含你的程序逻辑!getManagedSeesions 返回当前由这个service管理的所有对话所组成的一个map。被管理的会话是那些被加入service监听器的会话。它将被用来处理空闲的会话和其他的会话,这基于用户加入监听器的会话的类型。getManagedSessionCount 返回当前由这个service所管理的会话的数量。getSessionConfig 返回对话配置。getFilterChainBuilder 返回过滤器链创建者。如果想在会话建立的时候向其中添加新的过滤器,这个函数将是很有用的。getFilterChain 返回当前这个service的默认过滤器链。isActive 告知当前service是活动的还是不活动的。getActivationTime 当service获得的时候返回活动时间。当service已经不在活动的时候,这个函数将返回它最后一次活动的时间。broadcast 向service管理的所有会话发送信息。setSessionDataStructureFactory 这个方法将设置IoSessionDataStructureFactory,此工厂将为当前service所创建的会话提供相关数据结构。getScheduledWriteBytes 返回将要写的比特数(这些比特保存在内存中,它们等待着socket的写)。getScheduledWriteMessages 返回将要写的信息数(这些信息保存在内存中,它们等待着socket的写)。getStatistics 为service返回IoServiceStatistics对象。IoService细节 IoService在MINA中被两个非常重要的类所实现: IoAcceptor IoConnector 为了构建一个服务器,你需要选择一个IoAccrptor接口的实现。为了构建一个客户端,你需要一个IoConnector接口的实现。IoAcceptor 基本上这个接口被这样命名是因为accept()方法,它负责在一个服务器和客户端之间创建链接。服务器结构对内的请求。 在一些情况下,我们可以将这个借口命名为“Server”(这个新的名字来自MINA 3.0)。 我们有很多的方式来完成传输任务(TCP/UDP),所以对于这个接口也有多个实现。它不大可能需要你自己写一个实现。 我们对它有以下实现类: NioSocketAcceptor:非阻塞的Socket传输IoAcceptor NioDatagramAcceptor:非阻塞的UDP传输IoAcceptor AprSocketAcceptor:阻塞的Socket传输IoAcceptor,基于APR VmPipeSocketAcceptor:in-VM IoAcceptor 只需要选择一个你需要的。 以下是IoAcceptor的实现类图解:创建Acceptor 首先你要选择你需要的IoAcceptor的实例类型。你的这个选择将决定你在后期使用什么样的网络协议。让我们来看一个它是如何工作的示例: 就是这样!你已经创建了一个TCP服务器。如果你想创建一个UDP服务器,你只需要简单地更换第一行代码:结束 这个服务器可以通过调用dispose()方法停止。服务器只有在所有挂起的会话都被解决之后才会停止: 你也可以通过向这个方法传送一个loolean值然后等待所有的线程都被执行:状态 你可以通过调用以下方法获得IoService的状态: isActive():如果服务可以接受请求则值为true isDisposing():当dispose()方法已经被执行过则它返回true。当服务已经停止的话它将没有返回值(一些会话可能已经被执行了)。 isDisposed():当dispose(boolean)方法已经被执行则它返回true,此时处理的线程已经完成了。管理IoHandler 如果服务实例化后你可以向其添加IoHandler或获取与其绑定的IoHandler。你只需要调用setHandler(IoHandler)或getHandler()方法。管理过滤器链 如果你想要管理过滤器链,你需要调用getFilterChain()方法。以下是一个例子: 你也可以事先创建一个过滤器链,然后再将它加入服务:IoConnector 就如我们需要IoAcceptor来构建服务器,你需要为客户端实现IoConnector接口。同样,我们已经有了很多实现类: NioSocketConnector:非阻塞的Socket传输IoConnector NioDatagramconnector:非阻塞的UDP传输IoConnector AprSocketConnetor:阻塞的Socket传输IoConnector,基于APR ProxyConnector:一个提供代理支持的IoConnector SerialConnector:一个提供串口传输功能的IoConnector VmPipeConnector:in-Vm IoConnector 只需要选择一个你需要的。 以下是IoConnector的实现类图解:第四章会话 会话是MINA的核心:每当客户端连接到服务器,一个新的会话就会被建立,它会被保存在内存中直到客户端断开连接。 会话用来保存与链接相关的固定信息,外加一些服务器恢复客户端请求时所要用到的信息,还有在整个会话生存期中有用的信息。会话状态 会话有它自己的状态,这种状态会不断的变化。 已连接的:会话已经被创建并且可用 空闲:这个回话在一段时间(这段时间是可配置的)里没有处理任何请求o 读空闲:在一段时间里没有读操作o 写空闲:在一段时间里没有写操作o 全部空闲:在一段时间里没有读写操作 正在关闭:会话正在被关闭(剩余的信息将被刷新清理,会话将被终止) 已关闭:会话已经被关闭了,不能再通过它做任何事情 下边的图片展示了所有的状态以及他们之间的转化关系:配置 我们可以为一个会话设置很多不同的参数: 接收缓存的大小 发送缓存的大小 空闲时间 写超时时间 还有一些其他的配置,它们将依赖于所使用的传输协议类型(看第六章传输协议)管理用户定义的属性 为了以后的使用保存一些数据是必须的。这些数据使用与会话相联系的专用数据结构来存储。这是一个数值对,它可以用来存储开发人员希望保存的数据。 例如,如果你想记录从会话创建以来收到的请求次数,这将很容易将其保存到一个map中:只需要创建一个与这个值相联系的值对。 我们又一种方式来处理存储在会话中的属性:一个属性是一个key/value值对,我们可以在seesion容器中添加、删除或读取这个值对。 这个容器在会话创建的时候将被自动建立,同时在会话关闭的时候将被自动删除。定义容器 就像我们说的,这个容器是一个key/value值对,它默认是Map类型的,如果有人想处理长寿命数据或想在数据很大的时候避免保存所有的数据,此时我们也可以定义其他的数据结构:在会话创建的时候,我们可以实现一个接口和一个工厂以用来创建这个容器。 下边的代码段演示了如何在会话初始化的时候创建一个容器: 下边的代码实现了一个工厂接口,用它我们可以定义另外类型的容器:过滤器链 每一个会话都与一个过滤器链相联系,过滤器会处理接收到的请求和发送出去的消息。这些过滤器链为每一个会话指定,尽管大多数情况,我们对存在的会话将使用相同的过滤器链。 无论如何,我们可以为一个单独的会话动态的修改过滤器链,例如为一个指定的会话添加一个Logger过滤器。统计 一个对话通常还会保存一些数据,这些数据显示了这个会话都做了什么: 接收到和发送出去的比特数 接收到和发送出去的信息数 空闲状态 吞吐量 还有一些其他的有用信息。Handler 最后也是相当重要的一部分,一个会话与一个Handler相联系,它负责调度你程序中的信息。handler还会通过调用write()方法使用会话发送包装好的会话信息。第五章过滤器 IoFilter是MINA中的一个核心结构,它提供了非常重要的规则。它过滤IoService和IoHandler之间的所有I/O事件和请求。如果你有web编程的经验,你可能会认为它是Servlet过滤器的堂兄弟。许多拆箱即用的过滤器是为了加快网络程序开发的步伐,通常会使用以下过滤器简化典型的横切关注点(AOP即面相切面编程,其主要意图是把业务无关的东西剥离出去,我们比较常用的比如事务处理,把开始和提交事务形象的当成一个“点”或者“面”,比如spring。实现原理主要有动态代理和修改字节码): LoggingFilter记录所有事件和请求的日志 ProtocolCodecFilter过滤器将对内的ByteBuffer信息转换成POJO(简单地Java对象),反之亦然 CompressionFilter过滤器压缩所有的数据 SSLFilter过滤器将添加SSL-TLS-StartTLS支持 还有更多 在这本手册中,我们将为一个真实世界示例逐步实现一个IoFilter。通常实现一个IoFilter是很容易的,但是你还需要知道MINA内部结构的细节。我们将介绍一些相关的内部属性。现有的过滤器 我们已经实现了很多过滤器。下表列出了所有已经存在的过滤器,还有它们的简短描述。有选择的重载事件 你可以扩展一个IoAdaptor而不是直接实现一个IoFilter。除非重载了,否则接收到的事件将直接传送到下一个过滤器:转换一个写请求 如果你想通过IoSession.write()方法来转换一个对内的请求信息,事情将变得很棘手。例如,如果你的过滤器希望将HighLevelMessage转换成LowLevelMessage,而此时是由HighLevelMessage对象调用IoSession.write()方法。你可以向你的过滤器的filterWrite()方法中插入适当的转换代码,并认为这样就行了。无论如何,你还需要关注messageSent事件,因为IoHandler或接下来的过滤器将会期待HighLevelMessage调用messageSent()方法,并把HighLevelMessage作为其参数,因为当调用者实际上写了HighLevelMessage的时候,调用者却发送了LowLevelMessage是不理智的。因此,所以当你的过滤器执行转换工作的时候你需要实现filterWrite()和messageSent()两个方法。 请注意即使输入的对象和输出的对象即使完全相同,你仍然需要实现相似的机制,因为IoSession.write()的调用者将指望着它messageSent()处理函数中所写的东西。 让我们假设你定义了一个将String转换成char数据的过滤器。你的过滤器的filterWrite()方法看起来如下: 现在,我们在messageSent()中要做相反的事情: 这个Sting-to-ByteBuffer转换如何?我们可以做得更有效,因为我们不需要重写原来的信息(String)。无论如何,下边的代码比我们给出的示例更复杂一些: 如果你是用MINA 2.0,它将与1.0和1.1版有所不同。详细信息请查看CompressionFilter和RequestResponseFilter的信息。过滤sessionCreated事件的时候要小心 sessionCreated是一个特殊的事件,它必须在I/O处理线程中进行处理(看线程模块模板)。永远不要把sessionCreated事件传给其他的线程。小心空缓冲 在一些情况中MINA将空缓冲最为内部的信号。空缓冲有时候会成为错误,因为有时候它是因为各种异常造成的,例如IndexOutOfBoundsException。这一小节将介绍如何避免这种意外情况。 ProtocolCodecFilter使用一个空缓冲(buf.hasRemaining() = 0)来标记信息的结束。如果你的过滤器被放在protocolCodecFilter之前,如果你的过滤器实现可能会产生空换成的异常的时候,请在protocolCodecFilter中确保它发送给另外一个过滤器: 你是否需要向每一个过滤器中都插入if判断块呢?很幸运,你不需要这样做。下边是一些处理空缓冲的金玉良言: 如果你的代码不会出任何问题包括空缓冲,那么你不需要添加if块 如果你的过滤器被放在ProtocolCodecFilter之后,你不需要添加if块 其他情况,你就需要添加if块了 如果你需要if判断块,请记住你不需要总是按照上边例子写。你可以在任何地方检测是否有空缓冲,只要你的过滤器不会抛出意想不到的异常就可以了。第六章传输APR传输介绍 APR(Apache Portable Runtime/线程池)提供更好的扩展性、性能和与本地系统的更好整合。APR被MINA所支持。在这一章中,我们将接触到如何使用MINA中的APR进行传输。我们将使用时间服务器来展示。先决条件APR传输依赖以下部件APR库从apache的网站下载并安装适合于你的平台的库/dist/tomcat/tomcat-connectors/native/。 JNI wrapper(tomcat-apr-5.5.23.jar)jar包附带在发行包中 将本地库的地址加入PATH环境变量中使用APR传输 让我们看一看基于NIO的时间服务器实现是怎样的: 让我们看一看如何使用APR传输: 我们只是简单地将NioSocketAcceptor改为了AprSocketAceeptor。就只这样,现在我们的时间服务器就可以使用APR传输了。 剩余部分仍然是相同的。串口传输 在MINA 2.0中你可以像连接到一个TCP/IP端口一样连接到一个串口。获得MINA 2.0 你可以下载最新的MINA编译版(2.0.2) 如果你更趋向于从代码自己构建MINA,请查阅开发者手册。先决条件有用的信息 再从一个Java程序访问串口之前你需要一个本地库(.Dll或.so这依赖于你的系统)。MINA使用来自RXTX.org的库:/pub/rxtx/rxtx-2.1-7-bins-r2.zip
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 驻村工作队疫情防控工作总结模版
- 湖南省湘一名校联盟2024-2025学年高一下学期期中考试历史试题(原卷版)
- 山东省济宁市2025年高考模拟考试语文试题及答案(济宁三模)
- 机械制图基础知识规范
- 中职学生政治思想个人总结模版
- 前台收银年终总结模版
- 症状性癫痫综合征的临床护理
- 学前儿童发展 课件 第11章 学前儿童情绪的发展
- 解码新质生产力
- 离心泵操作与维护培训
- 注册安全工程师中级建筑施工安全生产专业实务(建筑施工安全类案例)模拟试卷1(共426题)
- 2025届广西柳州市名校高考冲刺押题(最后一卷)化学试卷含解析
- 统编版高中语文必修下册 文言文翻译及文言知识总结
- 业主投诉处理制度
- 风电砼塔吊装安全交底
- 第17课 明朝的灭亡和清朝的建立 教案2024-2025学年七年级历史下册新课标
- 2025年博士思政面试题及答案
- 储备林可行性研究报告
- 汽车车载网络控制技术 课件 模块3 汽车车载网络系统故障检测与诊断
- 想应聘铁路简历模板
- 生物安全管理体系文件
评论
0/150
提交评论