MINA学习笔记(一)

 

MINA 学习笔记   (version MIAN - 2.0)

 

写在前头:

本文档为学习 MINA 官方文档中的摘抄和记录,所有记录都是一些关键点,或比较重要的、有代表性的地方。

 

学习目的:

以计算机网络、Java NIO、Java 并发机制 为基础,以 MINA 为开发框架,最终实现文本、图片、语音、视频的高效传输。

 

学习资源:

官方首页 -- http://mina.apache.org/

文档首页 -- http://mina.apache.org/documentation.html

 

一、 ACUS2007.pdf

================================================================================

1. 特性: 

   1) 基于 Java NIO,因此具有 非阻塞、异步、事件驱动 的特性

   2) 对 NIO 包装和提供了方便的访问方法,包括:auto-expanding, string encoding

   3) allocate from the Heap or Stack

2. 结构

   1) IoService 

         |--- IoAcceptor  (act as a server)

         |--- IoConnector (act as a client)

         |--- IoSession   (for a Connection)

                work for a session is serialized

   2) IoProcessor         (one thread default)

        you can add more IoProcessor Threads,

      at least one per CPU core

   3) IoFilter chain

   4) IoHandler 

3. 应用模式建议

   • use ExecutorFilter as first in chain

     unless you need really low latency

   • use ProtocolCodecFilter

     convert the wire protocol into a Java representation

   • put application logic into an IoHandler

   • store state in the IoSession

   • minimum of Java 5

     java.util.concurrent rocks!

 

二、JavaOne2008.pdf

================================================================================

1. MINA结构图

 

2. 异步的消息发送(IoSession & IoBuffer)

   /******* e.g *******/

   CharsetEncoder encoder = Charset.forName(System.getProperty("file.encoding")).newEncoder();

   IoSession session = ...

   IoBuffer buffer = IoBuffer.allocate(BUFFER_SIZE);

   buffer.setAutoExpand(true)

         .putString("It is ", encoder)

         .putString(new Date().toString(), encoder)

         .putString(" now.\r\n", encoder).flip();

   //异步的消息发送。  为什么?

   session.write(buffer);

 

3. IoHandler   

          实现IoHandler接口,添加自己的业务逻辑

   /******* e.g *******/

   public class EchoHandler implements IoHandler {

       public void messageReceived(IoSession session, Object msg) {

           IoBuffer buffer = (IoBuffer)msg;

           session.write(buffer);

       }

 

       public void exceptionCaught(IoSession session, Throwable e) {

           session.close();

       }

 

       public void sessionOpened(IoSession session) {...}

       public void sessionIdle(IoSession session, IdleStatus stat) {...}

       public void sessionClosed(IoSession session) {...}

       public void messageSent(IoSession session, Object msg) {..}

   }

 

4. IoService --> IoAcceptor (as a Server)

   public class Main {

       public static void main(String[] args) {

           IoAcceptor acceptor = new NioSocketAcceptor();

           acceptor.setHandler(new EchoHandler());

           acceptor.bind(new InetSocketAddress(8080);

           ...

           acceptor.unbind(new InetSocketAddress(8080);

       }

   }

 

5. IoService --> IoConnector (as a Client)

   public class Main {

       public static void main(String[] args) {

           IoConnector connector = new NioSocketConnector();

           connector.setHandler(new MyHandler());

           ConnectFuture future = connector.connect(

                                      new InetSocketAddress("localhost", 8080));

           IoSession session = future.await().getSession();

           session.write(...).await();

           session.close().await();   

 

6. IoFilterChain & IoFilter

   // Enable Loggin.

   acceptor.getFilterChain().addLast("logger", new LoggingFilter());

 

   // Enable SSL.

   acceptor.getFilterChain().addLast("ssl", new SslFilter());

 

   // Enable Compression for an individual session

   acceptor.getFilterChain().addBefore("ssl", "compressor", new CompressorFilter());

 

   // Clear all of them

   acceptor.getFilterChain().clear();   

 

7. ProtocolCodecFilter

 

   [ProtocolCodecFactory]

   |--------------------------|                         [IoFilterChain]

   | POJO --> IoBuffer  |                   |----------------------------|

   | ProtocolEncoder   |                   |                                     |

   | -----------------------  =======>   ProtocolCodecFilter |

   | ProtocolDecoder   |                   |                                     | 

   | IoBuffer --> POJO  |                   |----------------------------|

   |--------------------------|         

 

   1) TextLineCodecFactory 

       public class EchoHandler extends IoHandlerAdapter {

           public void messageReceived(IoSession s, Object m) {

               s.write((String) m); // 由于 Filter 已将内容转化为 String

           }

           ...

       }

       ... 

       acceptor.getFilterChain().addLast(new ProtocolCodecFilter(new TextLineCodecFactory()));   

 

   2) HttpCodecFactory (略)

 

   3) ExecutorFilter

      acceptor.getFilterChain().addLast("executor", new ExecutorFilter(

                                                    new OrderedThreadPoolExecutor()));

                                               //or new UnorderedThreadPoolExecutor()));

8. << Management >> using JMX

    public class EchoHandler extends IoHandlerAdapter {

        public void messageReceived(IoSession s, Object m) {

            s.write((String) m);

        }

        ...

    }

 

9. For More Information

    Vibrant community – that's what we are.

    WWW – MINA.apache.org

    E-mail – users@mina.apache.org

             trustin@apache.org

 

三、MINA in Real Life.pdf

================================================================================

1. MINA结构图 (注意 Session 的位置从 IoHandler 换到了 IoService)

 

2. 工作流程图

 

3. A more complex Use Case

   Apache Directory Server, it's include some features below:

   1) TCP and UDP

   2) Simple or Two levels protocols

   3) Binary messages

   4) Multiple handlers

   5) Potentially hundred of thousands connections

 

4. Do's and Don'ts

   Do's !!!

    • Follow the KISS principle

    • Keep the chain short

    • Do not use an executor if not needed

    • Tune the number of IoProcessors

    • Use only one codec filter

    • If you have a problem, then your codec/handler probably sucks...

 

   DON'Ts !!!

    • Don't use the logging filter. Use Log4j.

    • Your filter must be threadsafe

    • Don't expect that you will receive data in one single block

    • Don't forget about the negative impact Nagle's algorithm has on performance

    • Don't use Direct buffers unless absolutely needed

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值