directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Directory Wiki] Update of "MinaTutorialInChinese" by donald
Date Sat, 06 Aug 2005 01:22:18 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Directory Wiki" for change notification.

The following page has been changed by donald:
http://wiki.apache.org/directory/MinaTutorialInChinese

------------------------------------------------------------------------------
  
  attachment:Arch1.gif
  
+ 上面的图展示了MINA的IO层同客户端的交互。IoAcceptor执行所有底层IO,将他们翻译成抽象的IO事件,并把翻译过的事件和关联的IoSession
发送给IoHandler。
+ 
+ === IoSession ===
+ 
+ attachment:IoSession.gif
+ 
+ 一个代表了IoSession程序同一个远程实体的IO连接。通过IoSession,你可以写出message到远程实体,访问session的配置,并且更改session的属性。
+ 
+ === IoHandler ===
+ 
+ attachment:IoHandler.gif
+ 
+   * sessionCreated:当一个IO连接建立时被调用,这个方法在任何IO操作之前被调用,以便socket参数或session属性能够最先被设置。
+   * sessionOpened:在sessionCreated调用之后被调用。
+   * sessionClosed:当IO连接被关闭时被调用。
+   * sessionIdle:当在远程实体和用户程序之间没有数据传输的时候被调用。
+   * exceptionCaught:当IoAcceptor 或者你的IoHandler.中出现异常时被调用。
+   * dataRead:当从远程实体读取数据时被调用。
+   * dataWritten:当你想远程实体发出请求时被调用
+ 
+ 下面我们看看如何实现echo协议的IoHandler。
+ 
+ === 实现 IoHandler 以及启动代码 ===
+ 
+ 通常,应用需要继承IoHandlerAdapter并实现需要的方法:
+ 
+ {{{
+ package org.apache.mina.examples.echoserver;
+ 
+ import org.apache.mina.common.*;
+ import org.apache.mina.io.*;
+ 
+ public class EchoProtocolHandler extends IoHandlerAdapter
+ {
+     public void sessionCreated( IoSession session )
+     {
+         SessionConfig cfg = session.getConfig();
+         if( cfg instanceof SocketSessionConfig )
+         {
+             SocketSessionConfig scfg = ( SocketSessionConfig ) cfg ) ;
+ scfg.setSessionReceiveBufferSize( 2048 );
+         }
+     }
+ 
+     public void exceptionCaught( IoSession session, Throwable cause )
+     {
+         session.close();
+     }
+ 
+     public void dataRead( IoSession session, ByteBuffer rb )
+     {
+         // Write the received data back to remote peer
+         ByteBuffer wb = ByteBuffer.allocate( rb.remaining() );
+         wb.put( rb );
+         wb.flip();
+         session.write( wb, null );
+     }
+ }
+ }}}
+ 
+ 刚刚我们使用MINA实现echo协议,现在我们将handler绑定到一个server端口上。
+ 
+ {{{
+ package org.apache.mina.examples.echoserver;
+ 
+ import org.apache.mina.common.*;
+ import org.apache.mina.io.*;
+ import org.apache.mina.io.filter.*;
+ import org.apache.mina.registry.*;
+ 
+ public class Main
+ {
+     /** Choose your favorite port number. */
+     private static final int PORT = 8080;
+     
+ 
+     public static void main( String[] args ) throws Exception
+     {
+         ServiceRegistry registry = new SimpleServiceRegistry();
+         
+ // Bind
+         Service service = new Service( "echo",
+ TransportType.SOCKET, PORT );
+         registry.bind( service, new EchoProtocolHandler() );
+ 
+         System.out.println( "Listening on port " + PORT );
+     }
+ }
+ }}}
+ 
+ === 添加IoFilters ===
+ 
+ IoFilter提供了更加有力的方式来扩展MINA。它拦截所有的IO事件进行事件的预处理和后处理。你可以把它想象成Servlet的filters。IoFilter能够实现以下几种目的:
+ 
+   * 事件日志
+   * 性能检测
+   * 数据转换(e.g. SSL support)
+   * 防火墙…等等
+ 
+ attachment:Arch2.gif
+ 
+ 我们的echo协议handler不对任何IO事件进行日志。我们可以通过添加一个filter来增加日志能力。MINA提供了IoLoggingFilter来进行日志。我们只要添加日志filter到ServiceRegistry即可。
+ 
+ {{{
+ private static void addLogger( ServiceRegistry registry )
+ {
+     IoAcceptor acceptor =
+ registry.getIoAcceptor( TransportType.SOCKET );
+     acceptor.getFilterChain().addLast( "logger",
+  new IoLoggingFilter() );
+     System.out.println( "Logging ON" );
+ }
+ }}}
+ 
+ 想使用SSL?MINA也提供了一个SSL的filter,但它需要JDK1.5。
+ 
+ {{{
+ private static void addSSLSupport( ServiceRegistry registry )
+         throws Exception
+ {
+     SSLFilter sslFilter =
+         new SSLFilter( BogusSSLContextFactory.getInstance( true ) );
+     IoAcceptor acceptor =
+  registry.getIoAcceptor( TransportType.SOCKET );
+     acceptor.getFilterChain().addLast( "sslFilter", sslFilter );
+     System.out.println( "SSL ON" );
+ }
+ }}}
+ 
+ == 协议层: 实现反转Echo协议 ==
+ 
+ 在上面我们通过简单的echo server的例子学习了如何使用IO层,但是如果想实现复杂的如LDAP这样的协议怎么办呢?它似乎是一个恶梦,因为IO层没有帮助你分离‘message解析’和‘实际的业务逻辑(比如访问一个目录数据库)’。MINA提供了一个协议层来解决这个问题。协议层将ByteBuffer事件转换成高层的POJO事件:
+ 
+ attachment:Arch3.gif
+ 
+ 使用协议层必须实现5个接口:ProtocolHandler, ProtocolProvider, ProtocolCodecFactory,
ProtocolEncoder, 和 ProtocolDecoder:
+ 
+ attachment:ProtocolClasses.gif
+ 
+ 可能看上去有点麻烦,但是请注意ProtocolCodecFactory, ProtocolEncoder, 和
ProtocolDecoder是可以完全复用的;Apache的ASN1项目为MINA提供了ASN.1解码器,更通用的解码器如:XML、java对象序列化和简单的文本将在MINA的下一个版本中提供。一旦你实现了一个灵活的解码器,你可以在未来的应用中复用它,即使你不打算复用你的解码器,MINA也提供了一个很简单的方法来实现复杂的协议。(请参考高级主题)
+ 在这一章中,我们添加一个‘反转’server,它用于反转它接到的所有文本,我们通过它来示范如何编写一个协议层。
+ 
+ === ProtocolSession ===
+ 
+ attachment:ProtocolSession.gif
+ 
+ ProtocolSession同IO层的IoSession同样继承自Session。就像前面提到的,你只需撰写面向POJO的message而不是ByteBuffer的。ProtocolEncoder
将message对象解释成ByteBuffers以便IO层能够将他们输出到socket。
+ 
+ === ProtocolHandler ===
+ 
+ ProtocolHandler类似于IO层的IoHandler.dataRead和dataWritten方法被替换成messageReceived和messageSent。这是因为ProtocolDecoder
已经将IO层接收到的 ByteBuffers转换成了message对象。
+ 
+ === ProtocolEncoder 和 ProtocolDecoder ===
+ 
+ attachment:ProtocolCodec.gif
+ 
+ ProtocolEncoder 和ProtocolDecoder只有一个方法。ProtocolEncoder将message对象转换成一个ByteBuffer,而ProtocolDecoder将一个ByteBuffer转换成message对象。下面我们将学习如何实现这些接口。
+ 
+ === 实现 ProtocolHandler ===
+ 
+ 让我们首先实现一个ProtocolHandler。如同刚才实现IoHandler那样,我们继承ProtocolHandlerAdapter:
+ 
+ {{{
+ package org.apache.mina.examples.reverser;
+ 
+ import org.apache.mina.protocol.*;
+ 
+ public class ReverseProtocolHandler extends ProtocolHandlerAdapter
+ {
+     public void exceptionCaught( ProtocolSession session,
+ Throwable cause )
+     {
+         // Close connection when unexpected exception is caught.
+         session.close();
+     }
+ 
+     public void messageReceived( ProtocolSession session,
+ Object message )
+     {
+         // Reverse reveiced string
+         String str = message.toString();
+         StringBuffer buf = new StringBuffer( str.length() );
+         for( int i = str.length() - 1; i >= 0; i-- )
+         {
+             buf.append( str.charAt( i ) );
+         }
+ 
+         // and write it back.
+         session.write( buf.toString() );
+     }
+ }
+ }}}
+ 
+ === 实现 ProtocolProvider 以及启动代码 ===
+ 
+ 
+ 
+ 
+ 

Mime
View raw message