收藏 分销(赏)

MINA2官方教程翻译.doc

上传人:xrp****65 文档编号:7694371 上传时间:2025-01-12 格式:DOC 页数:25 大小:293.50KB 下载积分:10 金币
下载 相关 举报
MINA2官方教程翻译.doc_第1页
第1页 / 共25页
MINA2官方教程翻译.doc_第2页
第2页 / 共25页


点击查看更多>>
资源描述
MINA2官方教程翻译(1) 2.x与1.x的变化 文章分类:Java编程 一、包与命名   所有的类和方法严格使用驼峰法命名。 例如SSLFilter被更名为SslFilter,其它很多类也是如此。 所有NIO传输类在命名时增加‘Nio’前缀。 因为NIO并不只是socket/datagram传输的实现,所有‘Nio’前缀加在了所有的NIO传输类上。 改变之前: Java代码  1. SocketAcceptor acceptor = new SocketAcceptor();      改变之后: Java代码  1. SocketAcceptor acceptor = new NioSocketAcceptor();      Filter类被重新整理进多重子包内。 随着框架自带的filter实现的数量的增加,所有的filter都被移动到适当的子包中(例如,StreamWriteFilter移至org.apache.mina.filter.stream)。 *.support的所有包被移动到了其父包(或者其他包)中。 为了避免循环依赖,*.support包中的所有类都被移至其父包或者其他包中。你可以在IDE(例如Eclipse)中简单的修正这些包的导入从而避免编译错误。   二、Buffers   MINA ByteBuffer被重命名为IoBuffer。   因为MINA ByteBuffer与JDK中NIO ByteBuffer同名,很多用户发现与其组员沟通时存在很多困难。根据用户的反馈,我们将MINA ByteBuffer重命名为IoBuffer,这不仅使类名称简化,也是类名称更加明晰。   放弃Buffer池,默认使用IoBuffer.allocate(int)来分配heap buffer。   · acquire()与release()两个方法将不再是容易发生错误的。如果你愿意,你可以调用free()方法,但这是可选的。请自己承担使用这个方法的风险。 · 在大多数JVM中,框架内置的IoBuffer性能更加强劲、稳定。 Direct buffer池是MINA早期版本所标榜的众多特性之一。然而根据当今的尺度,在主流的JVM中direct buffers的表现要比heap buffers差。此外,当direct buffer memory的最大值没有被正确设定时,不可预期的OutOfMemoryError也经常出现。 为了使系统内置的IoBuffer性能更加强劲、稳定,Apache MINA项目组将默认的buffer类型由direct改为heap。因为heap buffers并不需要池化,PooledByteBufferAllocator也被移除掉了。由于没有了池的概念,ByteBuffer.acquire() 和 ByteBuffer.release()也被移除掉了。 然而,如果使用的速度太快,分配heap buffers也会成为瓶颈。这是因为分配字节数据如要将所有的元素都置为0,这个操作是消耗内存带宽的。CachedBufferAllocator是针对这种情况使用的,但是在大多数情况下,你还是应该使用默认的SimpleBufferAllocator。   三、启动和配置   IoService的配置被简化了。   在1.x版本中,有很多种方式来配置IoService和它的子接口(例如 IoAcceptor 和 IoConnector)。基本上,有两种配置方法: 在调用bind() 或 connect()时,具体指定一个IoServiceConfig Java代码  1. SocketAcceptor acceptor = new SocketAcceptor();    2. SocketAcceptorConfig myServiceConfig = new SocketAcceptorConfig();    3. myServiceConfig.setReuseAddress(true);    4. acceptor.bind(myHandler, myServiceConfig);      使用IoService.defaultConfig属性,此时不需要指定一个IoServiceConfig Java代码  1. SocketAcceptor acceptor = new SocketAcceptor();    2. acceptor.getDefaultConfig().setReuseAddress(true);    3. acceptor.bind(new InetSocketAddress(8080), myHandler);      配置IoFilterChain是另一个令人头痛的问题,因为除了IoServiceConfig内的IoFilterChainBuilder外,还有一个全局的IoFilterChainBuilder,这就意味着使用两个IoFilterChainBuilders来配置一个IoFilterChain。大多数用户使用全局的IoFilterChainBuilder来配置IoFilterChain,并且这就足够了。 针对这种复杂情况,MINA 2.0简化了网络应用程序的启动,请比较下面的代码与前面代码的不同 Java代码  1. SocketAcceptor acceptor = new SocketAcceptor();    2. acceptor.setReuseAddress(true);    3. acceptor.getFilterChain().addLast("myFilter1", new MyFirstFilter());    4. acceptor.getFilterChain().addLast("myFilter2", new MySecondFilter());    5. acceptor.getSessionConfig().setTcpNoDelay(true);    6.      7. // You can specify more than one addresses to bind to multiple addresses or interface cards.    8. acceptor.setLocalAddress(new InetSocketAddress(8080));    9. acceptor.setHandler(myHandler);    10.      11. acceptor.bind();    12.      13. // New API restricts one bind per acceptor, and  you can't bind more than once.    14. // The following statement will raise an exception.    15. acceptor.bind();      你也许意识到与Spring框架整合也将变得更加简单。   四、线程   ThreadModel被移除了。   最初引入ThreadModel的概念为的是简化一个IoService预定义的线程模式。然而,配置线程模式却变得非常简单以至于不能引入新的组建。与其易用性相比,线程模式带了更多的混乱。在2.x中,当你需要的时候,你必须明确的增加一个ExecutorFilter。   ExecutorFilter使用一个特定的Executor实现来维系事件顺序。 在1.x中,可以使用任意的Executor实现来来维系事件顺序,但2.x提供了两个新的ThreadPoolExecutor实现,OrderedThreadPoolExecutor和UnorderedThreadPoolExecutor,ExecutorFilter维系事件顺序,当以下两种情况:当使用默认构造方法时,ExecutorFilter创建一个OrderedThreadPoolExecutor,或者  明确指明使用OrderedThreadPoolExecutor时 OrderedThreadPoolExecutor 和 UnorderedThreadPoolExecutor内部使用了一些架构来防止发生OutOfMemoryError,所以你应该尽量使用这两个类而不是其他Executor的实现。   五、协议编解码   DemuxingProtocolCodecFactory被重写了。   新增了DemuxingProtocolEncoder和DemuxingProtocolDecoder两个类,DemuxingProtocolCodecFactory只是这两个类的外壳。register() 方法被重命名为addMessageEncoder() 和addMessageDecoder(),这个变化使混合使用多个encoders和decoders变得更加自由。 MessageEncoder接口也发生了改变,MessageEncoder.getMessageTypes()被移除了,当你调用addMessageEncoder(),你只需要指明信息的类型,encoder就可以进行正确的编码了。   六、集成   JMX集成被重新设计了。 Sping集成被简化了。 七、其他方面的改变 TransportType更名为TransportMetadata。 TransportType改名是因为它的角色是元数据而不仅仅是一种枚举。 IoSessionLogger被重新设计了。 IoSessionLogger现在实现了SLF4J Logger接口,所以你可以像声明简单SLF4J logger实例一样声明它,这个变化使你不必向其他不必要的部分暴露IoSessionLogger对象。另外,在使用MDC时,请考虑使用简单的MdcInjectionFilter,这时IoSessionLogger是没有必要的。 改变之前: Java代码  1. IoSessionLogger.debug(session, ...);      改变之后: Java代码  1. Logger logger = IoSessionLogger.getLogger(session);    2. logger.debug(...);    BroadcastIoSession被合并到IoSession中。 ReadThrottleFilterBuilder被ReadThrottleFilter替代并最终移除。 MINA2官方教程翻译(2) 快速上手指南 一、介绍   该教程通过构建一个time server,带你走进给予MINA的应用程序开发的大门,但在开始之前我们需要具备下面的必要条件: · MINA 2.x的核心包 · JDK 1.5 或更高版本 · SLF4J 1.3.0 或更高版本 1. Log4J 1.2的用户:slf4j-api.jar, slf4j-log4j12.jar, and Log4J 1.2.x 2. Log4J 1.3的用户:slf4j-api.jar, slf4j-log4j13.jar, and Log4J 1.3.x 3. java.util.logging的用户:slf4j-api.jar and slf4j-jdk14.jar 注意:请务必确认你所使用的slf4j-*.jar要与你的日志框架相匹配。例如,slf4j-log4j12.jar 和 log4j-1.3.x.jar不能在一起使用,否则会引起混乱。 我已经在Windows? 2000 professional 和 linux平台上测试了这个程序,如果你在运行这个程序的过程中遇到了问题,请立即联系我们的开发人员。 当然,这个程序是与开发环境(IDE, editors等等)无关的,它可以在任何你熟悉的平台中运行。另外,为了简化,编译命令与运行脚本都没有体现,如果你需要学习如何编译并运行java程序,请参考Java tutorial。 二、编写基于MINA框架的time server   我们从创建一个名为MinaTimeServer.java的文件开始,最初的代码如下: Java代码  1. public class MinaTimeServer {    2.      3.     public static void main(String[] args) {    4.         // code will go here next    5.     }    6. }      对所有人来说,这段代码应该是简单易懂的,我们只是简单的定义了一个main方法是这个程序能够正常运行起来。从现在开始,我们将逐步加入代码是其最终成为一个可用的server。首先,我们需要一个可以监听连接到来的对象,既然我们的程序是基于TCP/IP的,所以我们在程序中加入一个SocketAcceptor。 Java代码  1. import org.apache.mina.core.service.IoAcceptor;    2. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;    3.      4. public class MinaTimeServer    5. {    6.      7.     public static void main( String[] args )    8.     {    9.         IoAcceptor acceptor = new NioSocketAcceptor();    10.     }    11.      12. }      加入NioSocketAcceptor之后,我们可以继续定义一个handler类,并将其与NioSocketAcceptor绑定到一个端口上。 下面,我们在配置中增加一个filter,这个filter将把二进制数据或是协议相关的数据转换成为一个消息对象,反之亦然。我们使用现有的TextLine工厂类,以为它可以处理基于文本的信息(你不需要自己来实现编解码部分)。 Java代码  1. import java.nio.charset.Charset;    2.      3. import org.apache.mina.core.service.IoAcceptor;    4. import org.apache.mina.filter.codec.ProtocolCodecFilter;    5. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;    6. import org.apache.mina.filter.logging.LoggingFilter;    7. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;    8.      9. public class MinaTimeServer    10. {    11.     public static void main( String[] args )    12.     {    13.         IoAcceptor acceptor = new NioSocketAcceptor();    14.      15.         acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );    16.         acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));    17.     }    18. }      然后,我们定义一个handler,这个handler将对客户端的连接以及过去当前时间的请求做出服务。handler类必须实现IoHandler接口。对于大多数基于MINA的应用程序,这个操作无疑是一个很大的负担,因为它将处理客户端说有的请求。在这个教程中,我们的handler将继承自IoHandlerAdapter,这个类依照适配器模式来简化实现IoHandler接口所带来的代码量。 Java代码  1. import java.io.IOException;    2. import java.nio.charset.Charset;    3.      4. import org.apache.mina.core.service.IoAcceptor;    5. import org.apache.mina.filter.codec.ProtocolCodecFilter;    6. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;    7. import org.apache.mina.filter.logging.LoggingFilter;    8. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;    9.      10. public class MinaTimeServer    11. {    12.     public static void main( String[] args ) throws IOException    13.     {    14.         IoAcceptor acceptor = new NioSocketAcceptor();    15.      16.         acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );    17.         acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));    18.      19.         acceptor.setHandler(  new TimeServerHandler() );    20.     }    21. }      现在,我们在NioSocketAcceptor增加一些Socket相关的配置: Java代码  1. import java.io.IOException;    2. import java.nio.charset.Charset;    3.      4. import org.apache.mina.core.session.IdleStatus;    5. import org.apache.mina.core.service.IoAcceptor;    6. import org.apache.mina.filter.codec.ProtocolCodecFilter;    7. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;    8. import org.apache.mina.filter.logging.LoggingFilter;    9. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;    10.      11. public class MinaTimeServer    12. {    13.     public static void main( String[] args ) throws IOException    14.     {    15.         IoAcceptor acceptor = new NioSocketAcceptor();    16.      17.         acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );    18.         acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));    19.      20.         acceptor.setHandler(  new TimeServerHandler() );    21. idle sessions    22.         acceptor.getSessionConfig().setReadBufferSize( 2048 );    23.         acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );    24.     }    25. }      在MinaTimeServer增加了两行新的内容,这些set方法分别设置了IoHandler、input buffer size和session对象上的idle属性。buffer size指明了底层操作系统应该给与新到来的数据分配多少空间;第二行指明了什么时候应该检测idle sessions。在setIdleTime这个方法中,第一参数指明了在检测session是否idle时,应该关心那一种活动,第二个参数指明了session变为idle状态时需要经过多长的时间。 handler的代码如下: Java代码  1. import java.util.Date;   2.       3. import org.apache.mina.core.session.IdleStatus;    4. import org.apache.mina.core.service.IoHandlerAdapter;    5. import org.apache.mina.core.session.IoSession;    6.      7. public class TimeServerHandler extends IoHandlerAdapter    8. {    9.     @Override    10.     public void exceptionCaught( IoSession session, Throwable cause ) throws Exception    11.     {    12.         cause.printStackTrace();    13.     }    14.      15.     @Override    16.     public void messageReceived( IoSession session, Object message ) throws Exception    17.     {    18.         String str = message.toString();    19.         if( str.trim().equalsIgnoreCase("quit") ) {    20.             session.close();    21.             return;    22.         }    23.      24.         Date date = new Date();    25.         session.write( date.toString() );    26.         System.out.println("Message written...");    27.     }    28.      29.     @Override    30.     public void sessionIdle( IoSession session, IdleStatus status ) throws Exception    31.     {    32.         System.out.println( "IDLE " + session.getIdleCount( status ));    33.     }    34. }      该类用到的方法有exceptionCaught、messageReceived和sessionIdle。在handler中,一定要定义exceptionCaught方法,该方法用来处理在远程连接中处理过程中发生的各种异常,如果这个方法没有被定义,我们可能不能发现这些异常。 在这个handler中,exceptionCaught方法只是简单地打印出异常堆栈信息并关闭连接,对于大多数程序来说,这是一种比较标准的操作,除非连接可以在异常条件下恢复。 messageReceived方法会接收客户端的数据并返回当前的的系统时间,如果从客户端接收到了消息‘quit’,则session会被关闭。与调用session.write(Object)的情况相同,不同的协议编解码器决定了传入该方法的对象(第二个参数)也是不同的。如果你没有指定协议编解码器,你最有可能接收到一个IoBuffer对象,当然,调用session.write(Object)也是一个IoBuffer对象。 当session持续idle的时间与acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 )设置的时间一致时,sessionIdle方法将被调用。 现在剩下的工作只是定义一个server监听的地址和端口了,当然还需要启动服务。代码如下:   正如你所见,这里调用了acceptor.setLocalAddress( new InetSocketAddress(PORT) );方法,该方法指明了server将在哪个IP和端口上监听。最后一步调用了IoAcceptor.bind()方法,该方法将端口与具体的客户端进程绑定在一起。 三、验证Time server   现在,我们编译上面的程序,编译完成后就可以运行并查看运行结果了。最简单的测试途径就是启动程序,并使用telnet与之建立连接:   Client Output Server Output user@myhost:~> telnet 127.0.0.1 9123  Trying 127.0.0.1...  Connected to 127.0.0.1.  Escape character is '^]'.  hello  Wed Oct 17 23:23:36 EDT 2007  quit  Connection closed by foreign host.  user@myhost:~> MINA Time server started.  Message written...   四、接下来   获取更多资源,请浏览MINA的Documentation。你也可以阅读其他教程。 MINA2官方教程翻译(3) MINA的应用程序架构 文章分类:Java编程 一、简介 有个问题经常被提出:基于MINA的应用程序应该是什么样的呢?这篇文章将给出一个答案。我们已经收集了很多基于MINA的描述信息。下面是架构图:  让我们在来关于一下细节 这张图片选取自Trustin Lee在JavaOne 2008上的报告"Rapid Network Application Development with Apache MINA“ 从广义上讲,基于MINA的应用程序分为3层 · I/O Service - 完成实际的I/O操作 · I/O Filter Chain - 将字节过滤或转换成为预想的数据结构,反之亦然  · I/O Handler - 完成实际的业务逻辑操作 那我们如何创建一个基于MINA的应用程序呢?   1. Create I/O service - 从现有的Services (*Acceptor)中选择一个或者创建自己的  2. Create Filter Chain - 从现有的Filters中选择或者创建一个传输request/response的自定义Filter 3. Create I/O Handler - 编写业务逻辑, 处理不同的报文 创建MINA程序就如上文所述的一样。   MINA2官方教程翻译(4) 日志配置 一、背景 MINA框架允许开发人员在编写基于MINA的应用程序时使用自己熟悉的日志系统。   二、SLF4J MINA框架使用Simple Logging Facade for Java (SLF4J)。你可以在这里 获取到更多关于SLF4J的信息,这种日志系统兼容各种日志系统的实现。你可能会使用log4j、java.util.logging或其他的日志系统,使用这种日志框架的好处在于如果你在开发过程中,将日志系统从java.util.logging改为log4j,你根本需要修改你的代码。 选择正确的jar包 Logging framework Required JARs Log4J 1.2.x slf4j-api.jar , slf4j-log4j12.jar Log4J 1.3.x slf4j-api.jar , slf4j-log4j13.jar java.util.logging slf4j-api.jar , slf4j-jdk14.jar Commons Logging slf4j-api.jar , slf4j-jcl.jar   下面几点还需要注意:   · 对于任意一种日志系统,slf4j-api.jar是必须的; · 重要:在classpath上不能放置多于一个日志系统实现jar包(例如slf4j-log4j12.jar and slf4j-jdk14.jar),这将导致日志出席不可预知的行为;  · slf4j-api.jar 和 slf4j-<impl>.jar的版本应该是一致的。   如果SLF4J配置正确,你可以继续配置你真正使用的日志系统(例如修改log4j.properties )。   重载Jakarta Commons Logging   SLF4J提供了一种机制可以使现有的应用程序从使用Jakarta Commons Logging变更为SLF4J而不需要修改代码,只需要将commons-loggong JAR文件充classpath中除去,并将jcl104-over-slf4j.jar 加入到classpath中。   三、log4j范例 我们以log4j为例,然后将下面的代码片段加入到log4j.properties中:   Properties代码  1. # Set root logger level to DEBUG and its only appender to A1.    2. log4j.rootLogger=DEBUG, A1    3.      4. # A1 is set to be a ConsoleAppender.    5. log4j.appender.A1=org.apache.log4j.ConsoleAppender    6.      7. # A1 uses PatternLayout.    8. log4j.appender.A1.layout=org.apache.log4j.PatternLayout    9. log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c{1} %x - %m%n      我们将这个文件放置在工程的src目录中,如果你使用IDE,当你测试代码是,你实际上是想把这个文件放置在classpath上。 注意 :这里只是在IoAcceptor 上设置了日志,但slf4j 可以在程序中广泛使用,有了它的帮助,你可以根据需要获取到有用的信息。 下面我们编写一个简单的server从而生成一些日志信息,这里我们使用EchoServer 的范例工程来增加日志:   Java代码  1. public static void main(String[] args) throws Exception {    2.         IoAcceptor acceptor = new SocketAcceptor();    3.         DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();    4.      5.         LoggingFilter loggingFilter = new LoggingFilter();    6.         chain.addLast("logging", loggingFilter);                      7.      8.         acceptor.setLocalAddress(new InetSocketAddress(PORT));    9.         acceptor.setHandler(new EchoProtocolHandler());    10.         acceptor.bind();    11.      12.         System.out.println("Listening on port " + PORT);    13. }     正如你所见,在EchoServer 范例中,我们删除了addLogger方法并新增加了两行代码。通过LoggingFilter 的引用,你可以在这里设置与IoAcceptor 相关的所有事件的日志级别。在这里,可以使用LoggingFilter 中的setLogLevel(IoEventType, LogLevel)方法来区分
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服