Apache Mina(一)

Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过Java nio技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。

Mina包的简介:

org.apache.mina.core.buffer 用于缓冲区的IoBuffer
org.apache.mina.core.service
org.apache.mina.transport.*
用于提供连接的service
org.apache.mina.core.session 用于提供两端状态的session
org.apache.mina.core.filterchain
org.apache.mina.filter.*
用于拦截所有IO事件和请求的filter chain和各类拦截器(在IoService和IoHandler之间)
org.apache.mina.handler.* 用于处理IO事件的handler
org.apache.mina.core.future 用于实现异步IO操作的 future
org.apache.mina.core.polling 用于实现IO轮询的的polling
org.apache.mina.proxy.* 用于实现代理的proxy

先介绍Mina几个重要接口:

  • IoServiece :这个接口在一个线程上负责套接字的建立,拥有自己的 Selector,监听是否有连接被建立。
  • IoProcessor :这个接口在另一个线程上负责检查是否有数据在通道上读写,也就是说它也拥有自己的 Selector,这是与我们使用 JAVA NIO 编码时的一个不同之处,通常在 JAVA NIO 编码中,我们都是使用一个 Selector,也就是不区分 IoService与 IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在 IoService 上的过滤器,并在过滤器链之后调用 IoHandler。
  • IoAccepter :相当于网络应用程序中的服务器端
  • IoConnector :相当于客户端
  • IoSession :当前客户端到服务器端的一个连接实例
  • IoHandler :这个接口负责编写业务逻辑,也就是接收、发送数据的地方。这也是实际开发过程中需要用户自己编写的部分代码。
  • IoFilter :过滤器用于悬接通讯层接口与业务层接口,这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的 encode与 decode是最为重要的、也是你在使用 Mina时最主要关注的地方。

MIINA架构图

在图中的模块链中,IoService 便是应用程序的入口,相当于我们前面代码中的 IoAccepter,IoAccepter 便是 IoService 的一个扩展接口。IoService 接口可以用来添加多个 IoFilter,这些 IoFilter 符合责任链模式并由 IoProcessor 线程负责调用。而 IoAccepter 在 ioService 接口的基础上还提供绑定某个通讯端口以及取消绑定的接口。

IoAcceptor acceptor = new SocketAcceptor();

上面代码中,相当于我们使用了 Socket 通讯方式作为服务的接入,当前版本的 MINA 还提供了除 SocketAccepter 外的基于数据报文通讯的 DatagramAccepter 以及基于管道通讯的 VmPipeAccepter。另外还包括串口通讯接入方式,目前基于串口通讯的接入方式已经在最新测试版的 MINA 中提供。你也可以自行实现 IoService 接口来使用自己的通讯方式。

而在上图中最右端也就是 IoHandler,这便是业务处理模块。在业务处理类中不需要去关心实际的通讯细节,只管处理客户端传输过来的信息即可。编写 Handler 类就是使用 MINA 开发网络应用程序的重心所在,相当于 MINA 已经帮你处理了所有的通讯方面的细节问题。为了简化 Handler 类,MINA 提供了 IoHandlerAdapter 类,此类仅仅是实现了 IoHandler 接口,但并不做任何处理。

一个 IoHandler 接口中具有如下一些方法(摘自 MINA 的 API 文档):

  • void exceptionCaught(IoSession session, Throwable cause)
    当接口中其他方法抛出异常未被捕获时触发此方法
  • void messageReceived(IoSession session, Object message)
    当接收到客户端的请求信息后触发此方法
  • void messageSent(IoSession session, Object message)
    当信息已经传送给客户端后触发此方法
  • void sessionClosed(IoSession session)
    当连接被关闭时触发,例如客户端程序意外退出等等
  • void sessionCreated(IoSession session)
    当一个新客户端连接后触发此方法
  • void sessionIdle(IoSession session, IdleStatus status)
    当连接空闲时触发此方法
  • void sessionOpened(IoSession session)
    当连接后打开时触发此方法,一般此方法与 sessionCreated 会被同时触发

前面我们提到 IoService 是负责底层通讯接入,而 IoHandler 是负责业务处理的。那么 MINA 架构图中的 IoFilter 作何用途呢?答案是你想作何用途都可以。但是有一个用途却是必须的,那就是作为 IoService 和 IoHandler 之间的桥梁。IoHandler 接口中最重要的一个方法是 messageReceived,这个方法的第二个参数是一个 Object 型的消息,总所周知,Object 是所有 Java 对象的基础,那到底谁来决定这个消息到底是什么类型呢?答案也就在这个 IoFilter 中。在前面使用的例子中,我们添加了一个 IoFilter 是 new ProtocolCodecFilter(new TextLineCodecFactory()),这个过滤器的作用是将来自客户端输入的信息转换成一行行的文本后传递给 IoHandler,因此我们可以在 messageReceived 中直接将 msg 对象强制转换成 String 对象。

而如果我们不提供任何过滤器的话,那么在 messageReceived 方法中的第二个参数类型就是一个 byte 的缓冲区,对应的类是 org.apache.mina.core.buffer.IoBuffer。虽然你也可以将解析客户端信息放在 IoHandler 中来做,但这并不是推荐的做法,使原来清晰的模型又模糊起来,变得 IoHandler 不只是业务处理,还得充当协议解析的任务。

MINA自身带有一些常用的过滤器,例如LoggingFilter(日志记录)、BlackListFilter(黑名单过滤)、CompressionFilter(压缩)、SSLFilter(SSL加密)等。

简单地来讲,就分为三层:

  1. I/O Service :负责处理I/O。
  2. I/O Filter Chain :负责编码处理,字节到数据结构或数据结构到字节的转换等,即非业务逻辑的操作。
  3. I/O Handle :负责处理业务逻辑。

客户端的通信过程:

  1. 通过SocketConnector同服务器端建立连接。
  2. 链接建立之后I/O的读写交给了I/O Processor线程,I/O Processor是多线程的。
  3. 通过I/O Processor读取的数据经过IoFilterChain里所有配置的IoFilter,IoFilter进行消息的过滤,格式的转换,在这个层面可以制定一些自定义的协议。
  4. 最后IoFilter将数据交给Handler进行业务处理,完成了整个读取的过程。
  5. 写入过程也是类似,只是刚好倒过来,通过IoSession.write写出数据,然后Handler进行写入的业务处理,处理完成后交给IoFilterChain,进行消息过滤和协议的转换,最后通过I/O Processor将数据写出到socket通道。

IoFilterChain作为消息过滤链

  1. 读取的时候是从低级协议到高级协议的过程,一般来说从byte字节逐渐转换成业务对象的过程。
  2. 写入的时候一般是从业务对象到字节byte的过程。

 客户端通信过程   IoSession贯穿整个通信过程的始终

创建服务器

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;public class MinaTimeServer {// 定义监听端口private static final int PORT = 6488;public static void main(String[] args) throws IOException {// 创建服务端监控线程IoAcceptor acceptor = new NioSocketAcceptor();acceptor.getSessionConfig().setReadBufferSize(2048);acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);// 设置日志记录器acceptor.getFilterChain().addLast("logger", new LoggingFilter());// 设置编码过滤器
        acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));// 指定业务逻辑处理器acceptor.setHandler(new TimeServerHandler());// 设置端口号acceptor.bind(new InetSocketAddress(PORT));// 启动监听线程
        acceptor.bind();}
}

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;/*** 服务器端业务逻辑*/
public class TimeServerHandler extends IoHandlerAdapter {/*** 连接创建事件*/@Overridepublic void sessionCreated(IoSession session){// 显示客户端的ip和端口
        System.out.println(session.getRemoteAddress().toString());}@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {cause.printStackTrace();}/*** 消息接收事件*/@Overridepublic void messageReceived(IoSession session, Object message) throws Exception {String strMsg = message.toString();if (strMsg.trim().equalsIgnoreCase("quit")) {session.close(true);return;}// 返回消息字符串session.write("Hi Client!");// 打印客户端传来的消息内容System.out.println("Message written : " + strMsg);}@Overridepublic void sessionIdle(IoSession session, IdleStatus status) throws Exception {System.out.println("IDLE" + session.getIdleCount(status));}}

客户端

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;public class MinaTimeClient {public static void main(String[] args){// 创建客户端连接器.NioSocketConnector connector = new NioSocketConnector();connector.getFilterChain().addLast("logger", new LoggingFilter());connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));// 设置连接超时检查时间connector.setConnectTimeoutCheckInterval(30);connector.setHandler(new TimeClientHandler());// 建立连接ConnectFuture cf = connector.connect(new InetSocketAddress("192.168.2.109", 6488));// 等待连接创建完成
        cf.awaitUninterruptibly();cf.getSession().write("Hi Server!");cf.getSession().write("quit");// 等待连接断开
        cf.getSession().getCloseFuture().awaitUninterruptibly();// 释放连接
        connector.dispose();}
}

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;public class TimeClientHandler extends IoHandlerAdapter {public void messageReceived(IoSession session, Object message) throws Exception {String content = message.toString();System.out.println("client receive a message is : " + content);}public void messageSent(IoSession session, Object message) throws Exception {System.out.println("messageSent -> :" + message);}}

http://my.oschina.net/ielts0909/blog?catalog=253154

http://www.blogjava.net/mikechen/archive/2012/03/15/371938.html

http://dxf1122.blog.163.com/blog/static/54041004200931371414356/

http://blog.sina.com.cn/s/blog_7abc61de0100sdoi.html

http://mina.apache.org/mina-project/documentation.html

http://wenku.baidu.com/view/b9af67c34028915f804dc292.html

http://wenku.baidu.com/view/46800bce0508763231121232.html

http://wenku.baidu.com/view/5ccc7935b90d6c85ec3ac6e7.html

Apache Mina相关推荐

  1. Apache Mina 介绍

    为什么80%的码农都做不了架构师?>>>    1.MINA 框架简介 下图为本人根据对MINA的简要理解,所画出来的框架简图: Apache MINA 是一个网络应用框架,有助于用 ...

  2. Apache Mina开发手册

    作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 一.介绍 Apache Mina是一个网络应用框架,简化用户开发高性能.高可扩展性的网络应用程序的难度.M ...

  3. java Mina sftp_java – 使用Apache Mina作为模拟/内存SFTP服务器进行单元测试

    我正在解决如何使用Apache Mina的麻烦.他们的文档对我无能为力的大脑来说有一点不足.我已经看到了有用的起始代码 Java SFTP server library? 我无法想像的是如何使用它.我 ...

  4. 搭建Apache Mina框架并实现Server与Client端的简单消息传递

    http://www.himigame.com/apache-mina/831.html :(作者新浪微博: @李华明Himi ) 转载自[黑米GameDev街区] 原文链接: http://www. ...

  5. 使用 Apache MINA 开发高性能网络应用程序

    http://www.ibm.com/developerworks/cn/opensource/os-cn-apmina/ Apache MINA(Multipurpose Infrastructur ...

  6. Apache MiNa 2 学习笔记

    http://blog.csdn.net/cgwcgw_/article/details/18402769 http://download.csdn.net/detail/xiaozhu_1986/2 ...

  7. Apache MiNa 实现多人聊天室

    Apache MiNa 实现多人聊天室 开发环境: System:Windows JavaSDK:1.6 IDE:eclipse.MyEclipse 6.6 开发依赖库: Jdk1.4+.mina-c ...

  8. Apache Mina Demo

    Mina主要是作为服务器端底层框架来实现数据处理,它的实现很简单,如下例所示: view plaincopy to clipboardprint? package com.gftech.mytool. ...

  9. org.apache.mina.core.RuntimeIoException: Failed to get the session 异常可能出现的原因

    org.apache.mina.core.RuntimeIoException: Failed to get the session. red5抛出此异常 原因是red5.properties中配置的 ...

  10. 【Apache Mina2.0开发之一】搭建Apache Mina框架并实现Server与Client端消息传递

    Hibernate系列学习阶段到此结束了,那么紧接着进入Apache Mina的开发学习,很多童鞋在微薄和QQ中疑问Himi为什么突然脱离游戏开发了,嘿嘿,其实可能更多的童鞋已经看出来了,Himi在偏 ...

最新文章

  1. PCL分割:Conditional Euclidean Clustering官方历程,在自己配置环境上调错
  2. C++访问属性和继承属性浅析
  3. iOS病毒XcodeGhost批量检测工具,开源Github(检测ipa文件)
  4. win7与ubuntu 13.04 64位双系统安装介绍
  5. 神经网络第五周tutorial解析
  6. go mod导入本地包的正确引入方法:require + replace
  7. Vuex状态管理方式
  8. Tmk吃汤饭(模拟)
  9. 集合的常用方法(增加、删除、并集、交集、差集、对等差分、超集和子集)
  10. vuejs 传参 向 子组件 父组件_Vue 2.6发布:新语法、性能改进、向3.0看齐
  11. 基于国产密码算法的开源OpenSSL密码库
  12. python调用matlab
  13. CADD课程学习(10)-- 模拟不同体系与小分子相互作用(MOE)
  14. 退出卸载360、QAX 天擎,无需密码
  15. matlab gui设计入门与实战,matlab gui编程教程
  16. 如何配置无线WiFi短信认证登录?
  17. WPF界面MahApps.Metro之应用
  18. 50个BA分析工具第四个-Business Case
  19. python opencv图片拼接、特征点匹配
  20. 一点体会:找工作这事儿

热门文章

  1. 人工智能与计算机软件的区别,人工智能和计算智能有什么区别呢?
  2. 软件测试工程师面试题答案分类详解-一家老牌培训机构内部绝密文件!
  3. 使用XCode打包ipa
  4. cad延伸命令怎么用_CAD拉伸怎么用
  5. MP2669GR锂电池充电管理芯片
  6. 有限元——ANSYS求解悬臂梁均布载荷问题
  7. 上手百度地图--开放平台必懂API使用场合(PC端)
  8. 【自然语言处理与文本分析】文本特征提取方法总结。关键词提取方法。公认效果较好的IDF,RCF。
  9. 「学习笔记」移动Web开发之flex布局9
  10. EFI基本概念之UDK2015定制EDKTOOL