MINA 基础学习一

原创 2013年12月04日 10:25:06

 

一、IoService接口

1、作用:IoService是创建服务的顶层接口,无论客户端还是服务端,都是从它继承实现的。

2、类结构

常用接口为:IoService,IoAcceptor,IoConnector

常用类为:NioSocketAcceptor,NioSocketConnector

类图如下:

 

 

先提出两个问题:

1. 为什么有了IoService接口还要定义AbstractIoService抽象类?

2. AbstractIoService抽象类与IoAcceptor(IoConnector)有什么区别?

分析:

    1. IoService接口声明了服务端的共有属性和行为;

    2. IoAcceptor接口继承了IoService接口,并添加了服务端特有的接口属性及方法,比如bind()方法,成为典型的服务端接口;

    3. IoConnector接口同样继承了IoService接口,并添加了客户端特有的接口属性及方法,比如connect()方法,成为典型的客户端接口;

---- IoService是IoAcceptor和IoConnector父接口,为什么不直接定义IoAcceptor和IoConnector接口呢,因为它们有共同的特点,比如共同属性,管理服务的方法等,所有IoService的出现是为了代码复用。

    4. AbstractIoService实现了IoService中管理服务的方法,比如getFilterChainBuilder方法---获得过滤器链;

----为什么有了IoService接口还要定义AbstractIoService抽象类?一样为了代码的复用!AbstractIoService抽象类实现了服务端或客户端的共有的管理服务的方法,不需要让IoService接口的子类重复的实现这些方法;

    5. AbstractIoAcceptor抽象类继承了AbstractIoService抽象类并实现了IoAcceptor接口,成为了拥有管理服务端实现功能的服务端类;我们常用的NioSocketAcceptor就是它的子类;

    6. AbstractIoConnector抽象类继承了AbstractIoService抽象类并实现了IoConnector接口,成为了拥有管理客户端实现功能的客户端类;我们常用的NioSocketConnector就是它的子类;

----AbstractIoService抽象类与IoAcceptor(IoConnector)有什么区别?很清楚,AbstractIoService抽象类实现的是共有的管理服务的方法,只有管理功能的一个类;而两个接口却是不同的两个服务角色----一个客户端,一个服务端。

//创建一个非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
//创建一个非阻塞的客户端
IoConnector connector = new NioSocketConnector();
二、IoSessionConfig

获得IoSession的配置对象IoSessionConfig,通过它可以设置Socket连接的一些选项。

a. void setReadBufferSize(int size)

这个方法设置读取缓冲的字节数,但一般不需要调用这个方法,因为IoProcessor 会自动调整缓冲的大小。你可以调用setMinReadBufferSize()、setMaxReadBufferSize()方法,这样无论IoProcessor 无论如何自动调整,都会在你指定的区间。

b. void setIdleTime(IdleStatus status,int idleTime):

 

这个方法设置关联在通道上的读、写或者是读写事件在指定时间内未发生,该通道就进入空闲状态。一旦调用这个方法,则每隔idleTime都会回调过滤器、IoHandler中的sessionIdle()方法。

 

c. void setWriteTimeout(int time):

这个方法设置写操作的超时时间。

d. void setUseReadOperation(boolean useReadOperation):

这个方法设置IoSession 的read()方法是否可用,默认是false。

 

 

// 获得IoSessionConfig对象
IoSessionConfig cfg=acceptor.getSessionConfig();
// 设置读取数据的缓冲区大小()
cfg.setReadBufferSize(2048);
// 读写通道10秒内无操作进入空闲状态
cfg.setIdleTime(IdleStatus.BOTH_IDLE, 10);
// 写操作超时时间10秒
cfg.setWriteTimeout(10);
 
三、IoFilter接口

Mina最主要的工作就是把底层传输的字节码转换为Java对象,提供给应用程序;或者把应用程序返回的结果转换为字节码,交给底层传输。这些都是由IoFilter完成的,因此IoFilterMina的精髓所在。

Mina程序中,IoFilter是必不可少的;有了它,Mina的层次结构才异常清晰:

IoFilter   ----   消息过滤

IoHandler  ----   业务处理

    Filter,过滤器的意思。IoFilterI/O操作的过滤器。IoFilterServlet中的过滤器一样,主要用于拦截和过滤网络传输中I/O操作的各种消息。在Mina 的官方文档中已经提到了IoFilter 的作用:

1)记录事件的日志(Mina默认提供了LoggingFilter

2)测量系统性能

3)信息验证

4)过载控制

5)信息的转换(主要就是编码和解码)

6)和其他更多的信息

    IoService实例会绑定一个DefaultIoFilterChainBuilder ---- 过滤器链,我们把自定义的各种过滤器(IoFilter)自由的插放在这个过滤器链上了,类似于一种可插拔的功能!

2.2.1类结构

常用接口为:IoFilterIoFilterChainBuilder

常用类为:IoFilterAdapterDefaultIoFilterChainBuilder

ProtocolCodecFilterLoggingFilter

类图如下:

先提出两个问题:

1. 在IoService中如何添加多个IoFilter?

2. 如何自定义协议编解码器?

分析:

a. IoFilter有2个实现类:IoFilterAdapter是个抽象的适配器类,我们可以根据需要扩展这个类,并且有选择的覆盖过滤器的方法;所有方法的默认把事件转发到下一个过滤器;查看源码如下:

 

 

public void sessionOpened(NextFilter nextFilter, IoSession session)throws Exception {
        nextFilter.sessionOpened(session);
  }
 

 

b .ReferenceCountingFilter封装了IoFilter实例,监看调用该filter的对象的个数,如果没有任何对象调用该IoFilter,就自动销毁IoFilter;查看源码如下:

 

 

public class ReferenceCountingFilter implements IoFilter {
    private final IoFilter filter;
 
    private int count = 0;
 
    public ReferenceCountingFilter(IoFilter filter) {
        this.filter = filter;
    }
 
    public void init() throws Exception {
        // no-op, will init on-demand in pre-add if count == 0
    }
    public void destroy() throws Exception {
           } ……………略
 

 

c. 实现IoFilterAdapter的类有多个,但是我们使用最多的就是

ProtocolCodecFilter----它是我们自定义编解码器的入口

 

添加过滤器----在IoService中如何添加多个IoFilter?如何代码,我添加了2个过滤器:LoggingFilter和TextLineCodecFactory(源码为入门的服务端程序)

// 创建一个非阻塞的server端的Socket
acceptor = new NioSocketAcceptor();
// 设置日志过滤器
acceptor.getFilterChain().addLast("logger",new LoggingFilter());
// 设置过滤器(使用Mina提供的文本换行符编解码器)
acceptor.getFilterChain().addLast(
		"codec",
		new ProtocolCodecFilter(new TextLineCodecFactory(Charset
				.forName("UTF-8"),
				LineDelimiter.WINDOWS.getValue(),
				LineDelimiter.WINDOWS.getValue())));
// 获得IoSessionConfig对象
IoSessionConfig cfg = acceptor.getSessionConfig();
// 读写通道10秒内无操作进入空闲状态
cfg.setIdleTime(IdleStatus.BOTH_IDLE, 10);

// 绑定逻辑处理器
acceptor.setHandler(new Demo1ServerHandler());
// 绑定端口
acceptor.bind(new InetSocketAddress(PORT));
logger.info("服务端启动成功...     端口号为:" + PORT);

 

如果要是使用LoggingFilter类,则需要需要导入slf4j-log4j12-1.7.5.jar、slf4j-api-1.7.5.jar、log4j-1.2.13.jar三个包,然后在src目录下面添加log4j的配置文件

 

 

log4j.rootLogger=DEBUG,MINA,file

log4j.appender.MINA=org.apache.log4j.ConsoleAppender    
 
log4j.appender.MINA.layout=org.apache.log4j.PatternLayout    
log4j.appender.MINA.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss,SSS} %-5p %c{1} %x - %m%n

log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/minademos.log
log4j.appender.file.MaxFileSize=5120KB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[VAMS][%d] %p | %m | [%t] %C.%M(%L)%n

 

 四、IoHandler接口

 

IoHandler是Mina实现其业务逻辑的顶级接口;它相当简单,你就理解它是根据事件触发的简单应用程序即可。

在IoHandler中定义了7个方法,根据I/O事件来触发对应的方法:

 

import java.io.IOException;
public interface IoHandler {
    void sessionCreated(IoSession session) throws Exception;
    void sessionOpened(IoSession session) throws Exception;
    void sessionClosed(IoSession session) throws Exception;
    void sessionIdle(IoSession session, IdleStatus status) throws Exception;
    void exceptionCaught(IoSession session, Throwable cause) throws Exception;
    void messageReceived(IoSession session, Object message) throws Exception;
    void messageSent(IoSession session, Object message) throws Exception;
}

 

sessionCreated:当一个新的连接建立时,由I/O processor thread调用;

 

sessionOpened:当连接打开是调用;

 

messageReceived:当接收了一个消息时调用;

 

messageSent:当一个消息被(IoSession#write)发送出去后调用;

 

sessionIdle:当连接进入空闲状态时调用;

 

sessionClosed:当连接关闭时调用;

 

exceptionCaught:当实现IoHandler的类抛出异常时调用;

 

    一般情况下,我们最关心的只有messageReceived方法,接收消息并处理,然后调用IoSession的write方法发送出消息!(注意:这里接收到的消息都是Java对象,在IoFilter中所有二进制数据都被解码啦!)

 

    一般情况下很少有人实现IoHandler接口,而是继承它的一个实现类IoHandlerAdapter,这样不用覆盖它的7个方法,只需要根据具体需求覆盖其中的几个方法就可以!

 

Iohandler的7个方法其实是根据session的4个状态值间变化来调用的:

 

Connected:会话被创建并使用;

 

Idle:会话在一段时间(可配置)内没有任何请求到达,进入空闲状态;

 

Closing:会话将被关闭(剩余message将被强制flush);

 

Closed:会话被关闭;

 

 

状态转换图如下

 

 

  • ba368336-3a94-35b5-bc7d-1620431dbdf5-thumb.bmp
  • 大小: 15.5 KB
  • e2f05f59-67a0-391a-a362-a60298179744-thumb.bmp
  • 大小: 15.1 KB
  • 96982499-c5d3-3d09-bfd3-7686aa302937-thumb.bmp
  • 大小: 9.4 KB

MINA框架源码分析(二)

上一篇我们通过实例学习了MINA框架的用法,发现用起来还是挺方便的,就那么几步就可以了,本着学东西必知其原理的观念,决定看看MINA的源码实现,好了,我们开始吧!         MINA源码对于客户...
  • hzw19920329
  • hzw19920329
  • 2016年08月10日 17:29
  • 3954

Apache-mina学习笔记,非常全都资料,附带大量实例

Apache Mina2 学习笔记             目录 引言. 3 一.    Mina入门. 3 第一步.下载使用的Jar包. 3 第二步.工程创建配置. ...
  • jintianhen1
  • jintianhen1
  • 2014年01月17日 11:02
  • 7132

Maven学习(一):maven基础

1、下载,并解压到固定文件夹中:如 D:\MyJAR\Use_JAR\apache-maven-3.2.3\bin 2、配置系统环境变量:新增M2_HOME : D:\MyJAR\Use_JAR\ap...
  • u012228718
  • u012228718
  • 2014年12月23日 20:16
  • 861

NIO通讯框架之阿堂教程:Mina学习笔记-高级进阶篇(三)

哦,前段时间阿堂一直比较忙,也没有写些什么了,想着高级进阶篇一直没有去弄,心中有觉得有些什么事情没有完成似的,所以就有了此文了。         这里阿堂要和网友分享的是自定义协议编解码,自定义协议...
  • younger_z
  • younger_z
  • 2015年09月08日 11:53
  • 467

Mina学习(1):mina实现简单服务端与客户端

mina是一个基于javaNio网络通信应用框架,使用mina可以轻松的搭建服务器,接下来将使用mina搭建一个小型的服务端 jar下载: 源代码–MinaServer.java package se...
  • c1481118216
  • c1481118216
  • 2016年10月05日 13:13
  • 1542

Mina学习(一)

首页  开源项目    问答   动弹 博客 翻译 资讯  专题    城市圈  Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP...
  • u012506661
  • u012506661
  • 2016年09月22日 18:40
  • 538

mina学习(一)

java.nio.* package包含以下内容: 1.Buffers :数据容器 2.Chartsets:可以设置bytes和Unicode的容器 3.Channels:代表连接实体的IO的操...
  • xll_2013
  • xll_2013
  • 2016年02月24日 22:36
  • 62

C++基础学习教程(一)

开始自己的C++复习进阶之路。 声明: 这次写的博文纯当是一个回顾复习的教程,一些非常基础的知识将不再出现,或者一掠而过,这次的主要风格就是示例代码很多~~~ 所有代码在Ubuntu...
  • hu1020935219
  • hu1020935219
  • 2014年06月12日 14:30
  • 5769

Java Mina-2.0.16框架学习使用

Java Mina框架学习使用 本文使用mina-2.0.16.jar Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架...
  • mazaiting
  • mazaiting
  • 2017年09月29日 00:57
  • 248

[学习《算法导论》] 第一部分 基础知识

算法导论第一章基础知识
  • u011232064
  • u011232064
  • 2016年10月04日 23:31
  • 725
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MINA 基础学习一
举报原因:
原因补充:

(最多只允许输入30个字)