您的位置:首页 > 移动开发

Mina(Multipurpose Infrastructure for Network Applications)完全文档

2007-10-08 11:03 316 查看
 
 
Mina文档
Nio:
NIO是一个基于事件的IO架构,最基本的思想就是:有事件我通知你,你再去做你的事情,没事件时你大可以节约大把时间去做其它任何事情。而且NIO的主线程only one,不像传统的模型,需要N个线程去,也减轻了JVM的工作量,使得JVM处理任务时显得更加高效。
Mina 综述
•         Multipurpose Infrastructure for Network Applications
•         一个基于非阻塞I/O的网络框架。
•         高可维护性,高可复用性:网络I/O编码,消息的编/解码,业务逻辑互相分离。
•         与JMX结合。
•         使用sfj4作为log
•         支持UDP,支持客户端API。
•         由Netty2的作者Trustin Lee开始开发的。
•         相对容易进行单元测试
Mina总体结构:
 


IoSession
•持有连接(服务端或客户端)
•和每个事件一起通过
•主要方法
•write
•close
•get/setAttribute
IoHandler
 
•类似Servlet
• filter chain的结尾部分。
•主要方法:
•sessionOpened
•messageReceived
•sessionClosed
 
 
IoFilterChain
 
•一连串的IoFilter,和每个session对应
•可以为第个 IoConnector/IoAcceptor设置IoFilter模板。
•动态添加和移除。
IoFilters
 
•类似一个 ServletFilter
•观察事件流。
•主要方法:
•sessionOpened
•messageReceived
•filterWrite
•sessionClosed
IoAcceptor
•服务端入口
•接收访问的连接和到IoHandler的触发事件.
•主要方法:
•bind
IoConnector
•客户端入口
•向远程服务器发起连接,触发事件到IoHandler
•主要方法:
•connect
IoProcessor
内部组件
•为其下的连接执行读写数据的操作。
•每个连接与一个IoProcessor相关联(多个连接之间共享一个IoProcessor)。
 
Mina的简单示例:
1.配置环境:
(1).edu.jar: 类似java.util 和java.util.concurrent中的包.不用jdk5.0的,好像是因为向jdk1.4的兼容。http://dcl.mathcs.emory.edu/util/backport-util-concurrent
(2).junit-4.1.jar:在eclipse的插件中有 D:。。eclipse/plugins/org.junit4_4.1.0、junit-4.1.jar
(3).slf4j-api-1.3.0.jar,slf4j-jdk14-1.3.0.jar:
  mina中用slf4j,应该是commons-logging的替代。http://www.slf4j.org/download.html
察看mina的QA email:
 http://www.mail-archive.com/mina-dev@directory.apache.org/msg02252.htmlServer.java
 
package com.zkchen.mina.sample;
 
import java.net.InetSocketAddress;
 
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
 
public class Server   
{   
    private static final int SERVER_PORT = 8080;   
   
    public Server(){
     
    }
    public static void main( String[] args ) throws Throwable   
   {   
        IoAcceptor acceptor = new SocketAcceptor();   
        SocketAcceptorConfig cfg = new SocketAcceptorConfig();   
        cfg.setReuseAddress( true );   
        cfg.getFilterChain().addLast(   
                    "codec",   
                    new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) );   
        cfg.getFilterChain().addLast( "logger", new LoggingFilter() );   
        acceptor.bind(   
                new InetSocketAddress( SERVER_PORT ),   
                new ServerSessionHandler( ), cfg );   
   
        System.out.println( "The server Listening on port " + SERVER_PORT );   
    }   
}  
 
ServerHandler.java
 
package com.zkchen.mina.sample;
 
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
 
public class ServerHandler extends IoHandlerAdapter   
{   
    public void sessionOpened( IoSession session )   
    {   
    }   
   
    public void messageReceived( IoSession session, Object message )   
    {   
         if (!(message instanceof ByteBuffer)) {
                    return;
            }
            ByteBuffer rb = (ByteBuffer) message;
            // Write the received data back to remote peer
            ByteBuffer wb = ByteBuffer.allocate(rb.remaining());
            wb.put(rb);
            wb.flip();
            session.write("received message: "+wb);
    }   
   
   
    public void exceptionCaught( IoSession session, Throwable cause )   
    {   
        // close the connection on exceptional situation   
        session.close();   
    }   
}   
   
3.客户端代码:
Client.java
 
package com.zkchen.mina.sample;
 
import java.net.InetSocketAddress;
 
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.SocketConnector;
import org.apache.mina.transport.socket.nio.SocketConnectorConfig;
 
public class Client   
{   
    private static final String HOSTNAME = "localhost";   
    private static final int PORT = 8080;   
    private static final int CONNECT_TIMEOUT = 30; // seconds   
   
   
    public static void main( String[] args ) throws Throwable   
    {   
        SocketConnector connector = new SocketConnector();           
        // Configure the service.   
        SocketConnectorConfig cfg = new SocketConnectorConfig();   
        cfg.setConnectTimeout( CONNECT_TIMEOUT );   
          cfg.getFilterChain().addLast(   
                    "codec",   
                    new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) );   
   
        cfg.getFilterChain().addLast( "logger", new LoggingFilter() );   
        connector.connect(new InetSocketAddress( HOSTNAME, PORT ),    
                        new ClientHandler(), cfg );   
   
    }   
}   
ClientHandler.java
 
package com.zkchen.mina.sample;
 
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
 
public class ClientHandler extends IoHandlerAdapter {
 
      public ClientHandler() {
             super();
      }
 
      public void sessionOpened(IoSession session) {
             session.write("hello");
      }
 
      public void messageReceived(IoSession session, Object message) {
             System.out.println("in messageReceived!");
             if (!(message instanceof ByteBuffer)) {
                     return;
             }
             ByteBuffer rb = (ByteBuffer) message;
             // Write the received data back to remote peer
             ByteBuffer wb = ByteBuffer.allocate(rb.remaining());
             wb.put(rb);
             System.out.println(wb.toString());
             wb.flip();
             System.out.println(wb);
      }
 
      public void exceptionCaught(IoSession session, Throwable cause) {
             session.close();
      }
}
编译运行Server.java,编译运行Client.java.。
Server:
Client:
 
线程池的配置:
默认线程池的设置:
      IoServiceConfig config = acceptor.getDefaultConfig();  
       config .setThreadModel(ThreadModel.MANUAL);
     设置在Mina源代码ExecutorFilter.java中:
public ExecutorFilter()
    {
        this( new ThreadPoolExecutor(16, 16, 60, TimeUnit.SECONDS, new LinkedBlockingQueue() ) );
    }
I/O worker threads 的配置:
•        Acceptor thread :接收connector的连接,向I/O processor thread 的连接进行读写操作,默认有一个线程,不能配置。
•        Connector thread :连接到远程节点,向I/O processor thread 的连接进行读写操作,默认有一个线程,不能配置.。
•        I/O processor thread :执行读写操作。默认一个线程,可配置:
•        IoAcceptor acceptor = new SocketAcceptor(4, Executors.newCachedThreadPool());
   最好等于CPU的数量。
添加ExecutorFilter 到一个 IoFilterChain:
如果没有添加ExecutorFilter。IoHandler的业务逻辑实现将会在I/O processor thread中运行。称为单线程模式。在相应要求不高的应用中是可取的。
典型的网络应用需要一个ExecutorFilter来添加到IoFilterChain, 因为业务逻辑从I/Oprocessor threads有不同的资源使用模式,如果一个执行数据库操作的应用没有添加的话。当一个数据库操作发生时整个服务器可以阻塞,尤其是当数据库超载时。 IoServer添加ExecutorFilter当IoSession创建时:
IoAcceptor acceptor = ...;
DefaultIoFilterChainBuilder filterChainBuilder = acceptor.getDefaultConfig().getFilterChain();
filterChainBuilder.addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool());
ExecutorFilter没有生命周期。必须自己关闭。
ExecutorService executor = ...;
 
IoAcceptor acceptor = ...;
DefaultIoFilterChainBuilder filterChainBuilder = acceptor.getDefaultConfig().getFilterChain();
filterChainBuilder.addLast("threadPool", new ExecutorFilter(executor);
 
// Start the server.
acceptor.bind(...);
/ Shut down the server.
acceptor.unbind(...);
executor.shutdown();
 
当IoHandler应用有数据库操作时,最后添加ExecutorFilter。建议在一 个ProtocolCodecFilter应用后添加ExcutorFilter。因为protocol codec的特征是cpu-bound的。和I/O processor threads 相似。
 
IoAcceptor acceptor = ...;
DefaultIoFilterChainBuilder filterChainBuilder = acceptor.getDefaultConfig().getFilterChain();
// Add CPU-bound job first,
filterChainBuilder.addLast("codec", new ProtocolCodecFactory(...));
// and then a thread pool.
filterChainBuilder.addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool());
完成的server-push
•        功能: 服务器向客户端发送消息,并实时显示在客户端页面上。
•        消息:MsgBus运行时,产生Topic,相应的writer和reader。
•        Mina服务器:当产生新的消息(topic、writer、reader)时。把它发向客户端。
•        客户端:用flash-socket接收到消息,再用javascript实时添加到页面上。
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐