MINA框架使用总结

11 篇文章 0 订阅
6 篇文章 0 订阅

简单介绍:MINA框架是对java的NIO包的一个封装,简化了NIO程序开发的难度,封装了很多底层的细节,然开发者把精力集中到业务逻辑上来,最近做了一个相关的项目,为了备忘对MINA做一个总结。

下面这个start方法用来初始化MINA

private void start(int port, WebContext ctx)    
      throws IOException, InstantiationException   
        , IllegalAccessException, ClassNotFoundException {   
    //初始化Acceptor   
    NioSocketAcceptor acceptor = new NioSocketAcceptor(5);   
           
       java.util.concurrent.Executor threadPool = Executors.newFixedThreadPool(1500);//建立线程池   
       //加入过滤器(Filter)到Acceptor   
       acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));   
acceptor.getFilterChain().addLast("codec",    
       new ProtocolCodecFilter(new WebDecoder(),new WebEncoder()));   
       LoggingFilter filter = new LoggingFilter();   
    filter.setExceptionCaughtLogLevel(LogLevel.DEBUG);   
    filter.setMessageReceivedLogLevel(LogLevel.DEBUG);   
    filter.setMessageSentLogLevel(LogLevel.DEBUG);   
    filter.setSessionClosedLogLevel(LogLevel.DEBUG);   
    filter.setSessionCreatedLogLevel(LogLevel.DEBUG);   
    filter.setSessionIdleLogLevel(LogLevel.DEBUG);   
    filter.setSessionOpenedLogLevel(LogLevel.DEBUG);   
    acceptor.getFilterChain().addLast("logger", filter);    
           
       acceptor.setReuseAddress(true);//设置的是主服务监听的端口可以重用   
           
       acceptor.getSessionConfig().setReuseAddress(true);//设置每一个非主监听连接的端口可以重用   
       acceptor.getSessionConfig().setReceiveBufferSize(1024);//设置输入缓冲区的大小   
       acceptor.getSessionConfig().setSendBufferSize(10240);//设置输出缓冲区的大小   
//设置为非延迟发送,为true则不组装成大包发送,收到东西马上发出   
       acceptor.getSessionConfig().setTcpNoDelay(true);   
//设置主服务监听端口的监听队列的最大值为100,如果当前已经有100个连接,再新的连接来将被服务器拒绝   
       acceptor.setBacklog(100);   
       acceptor.setDefaultLocalAddress(new InetSocketAddress(port));   
       //加入处理器(Handler)到Acceptor   
       acceptor.setHandler(new WebHandler());   
    acceptor.bind();   
}  

 NioSocketAcceptor是 MINA 的适配器,一切都是从这里开始的。 MINA 中有个过滤器和处理器的概念,过滤器用来过滤数据,处理器用来处理数据。具体来说 MINA 的处理模型就是request->过滤器A->过滤器B->处理器->过滤器B->过滤器A->response,这里的request和response类似serlvet的request和response。

acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));   
//加入一个线程池到适配器,这里用的是jdk自带的线程池  

acceptor.getFilterChain().addLast("codec",    
        new ProtocolCodecFilter(new WebDecoder(),new WebEncoder()));   
//这里是处理逻辑的关键部位,请求的处理都是在WebDecoder类和WebEncoder类中处理,可以明显从命名上看出来一个是用来解码,另一个是用来编码,requet过来后先进入WebDecoder类(实现了ProtocolDecoder接口)进行解码处理,这里可以加入自己的逻辑把传进来的流解码成自己需要的信息。而WebEncoder类(实现了ProtocolEncoder接口)是进行编码,在这个类里面加入自己的逻辑把处理后的信息组装发送给客户端(response)。而在解码和编码过程中WebHandler(扩展了IoHandlerAdapter抽象类)起到了处理器的作用。   
//request->WebDecoder->WebHandler->WebEncode->response

现在详细描述一下request->WebDecoder->WebHandler->WebEncode->response的过程:

客户端发送一个请求到MINA服务器,这里相当于来了一个requet。请求首先来到

WebDecoder类(实现了ProtocolDecoder接口)中的    
boolean decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception{}方法   
/*  
参数in:用户请求信息全存在这里,读数据就从in这里读。  
参数out:用来输出处理后的数据到Filter的下一个过滤器,如果没有过滤器了就输出到WebHandler,这里有点和  
servelt的过滤器类似。利用out.write(Object object);这个函数可以把数据传到下一个Filter。我们可以自己定义  
一个对象,我们假设为Request,用它来传递消息,那末这里就可以写成out.write(new RequsetMessage());  
如果这个方法返回false,就是说当前逻辑包还没接收完(也就是当前的IoBuffer并没有包含足够的数据),需要再次  
执行decode方法(再次获取新的IoBuffer),用来获取足够的数据。如果返回值为true就表示可以不执行decode方  
法了,但是要激活handler方法,必须要调用out.write方法。  
public class RequestMessage{}//这里什么也不做  
*/  

然后到

WebHandler(扩展了IoHandlerAdapter抽象类)中的   
void messageReceived(IoSession session, Object message) throws Exception{}方法   
WriteFuture future = session.write(response);//session中必须加入这个代码,才会激活encode方法   
future.addListener(IoFutureListener.CLOSE);//这个的作用是发送完毕后关闭连接,加了就是短连接,不然是长连接   
IoFutureListener里面有个operationComplete(IoFuture future)方法,当流发送完成之后才调用这个方法。   
/*  
参数message:用来获取Filter传递过来的对象.对应代码RequestMessage request = (RequestMessage) message;  
参数session:用来发送数据到Filter.对应代码session.write(new ResponseMessage());  
public class ResponseMessage{}//这里什么也不做,假设存放处理后的数据  
注意:对于一个MINA程序而言,对于WebHandler类只生成一个对象,所以要考虑线程安全问题  
 */  

然后到

WebEncoder类(实现了ProtocolEncoder接口)中的   
boolean encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception{}    
方法   
/*  
参数message:用来获取上一个Filter节点的数据或者处理器的数据(如果这个过滤器为最靠近处理器的那个)  
ResponseMessage response = (ResponseMessage)message;  
参数out:用来输出数据到下一个Filter节点过或者到客户端,用out.write(Object encodedMessage)把数据发送  
出去,但是要注意的是,如果这个Filter下一个节点如果是客户端的话,那个这个encodedMessage数据必须为  
IoBuffer类型的,可以利用IoBuffer.wrap(byte[] byteArray)这个方法来格式化输出数据  
*/  


转载地址:http://www.blogjava.net/crespochen/archive/2009/04/17/266203.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值