mina

简介

mina是一个网络应用框架,能够使我们更容易开发出高性能高扩展的网络应用。基于java NIO,在TCP  UDP之上提供了抽象的异步事件驱动API。

Quick Start Guide

时间服务器

 1 import java.io.IOException;
 2 import java.net.InetSocketAddress;
 3 import java.nio.charset.Charset;
 4 
 5 import org.apache.mina.core.service.IoAcceptor;
 6 import org.apache.mina.core.session.IdleStatus;
 7 import org.apache.mina.filter.codec.ProtocolCodecFilter;
 8 import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
 9 import org.apache.mina.filter.logging.LoggingFilter;
10 import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
11 
12 public class MinaTimeServer {
13     private static final int PORT = 9123;
14 
15     public static void main(String[] args) throws IOException {
16 
17         IoAcceptor acceptor = new NioSocketAcceptor();
18         acceptor.getFilterChain().addLast("logger", new LoggingFilter());
19         acceptor.getFilterChain().addLast("codec",
20                 new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
21         // 处理客户端请求 实现IoHandlerAdapter
22         acceptor.setHandler(new TimeServerHandler());
23         // 设置缓冲区大小
24         acceptor.getSessionConfig().setReadBufferSize(2048);
25         // 当session空闲的时候检查的行为,每10秒前触发
26         acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
27         acceptor.bind(new InetSocketAddress(PORT));
28     }
View Code
 1 package com.mina;
 2 
 3 import java.util.Date;
 4 
 5 import org.apache.mina.core.service.IoHandlerAdapter;
 6 import org.apache.mina.core.session.IdleStatus;
 7 import org.apache.mina.core.session.IoSession;
 8 
 9 public class TimeServerHandler extends IoHandlerAdapter {
10     @Override
11     public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
12         cause.printStackTrace();
13     }
14 
15     @Override
16     public void messageReceived(IoSession session, Object message) throws Exception { // 获取客户端的message
17         String str = message.toString();
18         if (str.trim().equalsIgnoreCase("quit")) {
19             session.close();
20             return;
21         }
22 
23         Date date = new Date();
24         // 回写给client
25         session.write(date.toString() + "@@" + str);
26         System.out.println("Message written...");
27     }
28 
29     @Override // session保持空闲10秒以后触发执行,在acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
30                 // 10)设置
31     public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
32 
33         System.out.println("IDLE " + session.getIdleCount(status));
34     }
35 }
View Code

测试:

在dos中输入:  telnet 127.0.0.1 9123

mina 架构

基于mina的应用分三层:

  • I/O Service - 执行真实的I/O
  • I/O Filter Chain - 转换字节到指定的数据结构
  • I/O Handler - 处理业务逻辑

服务端架构:为每一个client创建一个session。                                client架构:

                       

 

日志过滤器

选择正确的jar

案例:

配置log4j.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
View Code

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

IoHandler Events

 

session

每一次client连接server,client和server都会创建一个新的session,用于存储持久化信息。

session状态:                                                                     检测session API:isActive()      isClosing()    isConnected() 

打开session:

session = connector.connect(address).getSession();

设置自定义属性:

   int counterValue = session.getAttribute( "counter" );      session.setAttribute( "counter", counterValue + 1 );

session返回应用数据:

  session.write( <your message> );

session配置及统计,详见官网API。

过滤器

过滤器在IOService和IoHandler之间吹所有的I/O时间和请求。

mina提供的过滤器:

实现一个自定义过滤器:继承IoFilterAdapter 

public class MyFilter extends IoFilterAdapter {
    @Override
    public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
        // Some logic here...
        nextFilter.sessionOpened(session);
        // Some other logic here...
    }
}
View Code

传输协议

APR传输:

导入必要的jar:tomcat-apr-5.5.23.jar  tomcat-native.jar

改变上面的时间服务器,change the NioSocketAcceptor to AprSocketAcceptor.

serial传输:详见http://mina.apache.org/mina-project/userguide/ch6-transports/serial-transport.html

 

Handler处理器

  • sessionCreated
  • sessionOpened
  • sessionClosed
  • sessionIdle
  • exceptionCaught
  • messageReceived
  • messageSent

I0Buffer

作为ByteBuffer的替代,不使用NIO缓冲区的理由有下面2个:

1)没有提供有用的getters和putters;

2)由于capacity是固定的,很难实现写入可变长度数据;

实现自动伸缩和扩展:

exp1

IoBuffer buffer = IoBuffer.allocate(8);
buffer.setAutoExpand(true);  //自动扩展
buffer.putString("12345678", encoder);
// Add more to this buffer
buffer.put((byte)10);


exp2

IoBuffer buffer = IoBuffer.allocate(16);
buffer.setAutoShrink(true);  //自动伸缩
buffer.put((byte)1);
System.out.println("Initial Buffer capacity = "+buffer.capacity());
buffer.shrink();
System.out.println("Initial Buffer capacity after shrink = "+buffer.capacity());
buffer.capacity(32);
System.out.println("Buffer capacity after incrementing capacity to 32 = "+buffer.capacity());
buffer.shrink();
System.out.println("Buffer capacity after shrink= "+buffer.capacity());
View Code

 

posted @ 2017-08-02 10:37  gaojy  阅读(412)  评论(0编辑  收藏  举报