Apache MINA 2 是一个开发高性能和高可伸缩性网络应用程序的网络应用框架。它提供了一个抽象的事件驱动的异步 API,可以使用 TCP/IP、UDP/IP、串口和虚拟机内部的管道等传输方式。Apache MINA 2 可以作为开发网络应用程序的一个良好基础。

Apache MINA是非常著名的基于java nio的通信框架,以前都是自己直接使用udp编程,新项目选型中考虑到网络通信可能会用到多种通信方式,因此使用了MINA。

本文结构:

(1)客户端和服务器代码 ;虽然是udp的,但是mina的优美的设计使得所有的通信方式能够以统一的形式使用,perfect。当然注意的是,不同的通信方式,背后的机理和有效的变量、状态是有区别的,所以要精通,那还是需要经验积累和学习的。

(2)超时 和Session的几个实际问题

(3)心跳 ,纠正几个错误

既然是使用,废话少说,直接整个可用的例子。当然了,这些代码也不是直接可用的,我们应用的逻辑有点复杂,不会这么简单使用的。

请参考mina的example包和文档http://mina.apache.org/udp-tutorial.html 。

版本2.0 RC1

1.1 服务器端

  1. NioDatagramAcceptor acceptor =  new  NioDatagramAcceptor();
  2. acceptor.setHandler(new  MyIoHandlerAdapter()); //你的业务处理,最简单的,可以extends IoHandlerAdapter
  3. DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
  4. chain.addLast("keep-alive" ,  new  HachiKeepAliveFilterInMina());  //心跳
  5. chain.addLast("toMessageTyep" ,  new  MyMessageEn_Decoder());
  6. //将传输的数据转换成你的业务数据格式。比如下面的是将数据转换成一行行的文本
  7. //acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
  8. chain.addLast("logger" ,  new  LoggingFilter());
  9. DatagramSessionConfig dcfg = acceptor.getSessionConfig();
  10. dcfg.setReuseAddress(true );
  11. acceptor.bind(new  InetSocketAddress(ClusterContext.getHeartBeatPort()));

1.2 客户端

  1. NioDatagramConnector connector =  new  NioDatagramConnector();
  2. connector.setConnectTimeoutMillis(60000L);
  3. connector.setConnectTimeoutCheckInterval(10000 );
  4. connector.setHandler(handler);
  5. DefaultIoFilterChainBuilder chain = connector.getFilterChain();
  6. chain.addLast("keep-alive" ,  new  HachiKeepAliveFilterInMina()); //心跳
  7. chain.addLast("toMessageTyep" ,  new  MyMessageEn_Decoder());
  8. chain.addLast("logger" ,  new  LoggingFilter());
  9. ConnectFuture connFuture = connector.connect(new  InetSocketAddress( "10.1.1.1" , 8001 ));
  10. connFuture.awaitUninterruptibly();
  11. IoSession session = connFuture.getSession();
  12. //发送消息长整型 1000
  13. IoBuffer buffer = IoBuffer.allocate(8 );
  14. buffer.putLong(1000 );
  15. buffer.flip();
  16. session.write(buffer);
  17. //关闭连接
  18. session.getCloseFuture().awaitUninterruptibly();
  19. connector.dispose();

2. 超时的几个经验总结:

udp session默认是60秒钟超时,此时状态为closing,数据就发不出去了。

Session的接口是IoSession,udp的最终实现是NioSession。如果交互在60秒内不能处理完成,就需要使用Keep-alive机制,即心跳机制。

3. 心跳 机制

在代码中已经使用了心跳机制,是通过mina的filter实现的,mina自身带的心跳机制好处在于,它附加了处理,让心跳消息不会传到业务层,在底层就完成了。

在上面代码实现中的HachiKeepAliveFilterInMina如下:

  1. public   class  HachiKeepAliveFilterInMina  extends  KeepAliveFilter {
  2. private   static   final   int  INTERVAL =  30 ; //in seconds
  3. private   static   final   int  TIMEOUT =  10 ;  //in seconds
  4. public  HachiKeepAliveFilterInMina(KeepAliveMessageFactory messageFactory) {
  5. super (messageFactory, IdleStatus.BOTH_IDLE,  new  ExceptionHandler(), INTERVAL, TIMEOUT);
  6. }
  7. public  HachiKeepAliveFilterInMina() {
  8. super ( new  KeepAliveMessageFactoryImpl(), IdleStatus.BOTH_IDLE,  new  ExceptionHandler(), INTERVAL, TIMEOUT);
  9. this .setForwardEvent( false );  //此消息不会继续传递,不会被业务层看见
  10. }
  11. }
  12. class  ExceptionHandler  implements  KeepAliveRequestTimeoutHandler {
  13. public   void  keepAliveRequestTimedOut(KeepAliveFilter filter, IoSession session)  throws  Exception {
  14. System.out.println("Connection lost, session will be closed" );
  15. session.close(true );
  16. }
  17. }
  18. /**
  19. * 继承于KeepAliveMessageFactory,当心跳机制启动的时候,需要该工厂类来判断和定制心跳消息
  20. * @author Liu Liu
  21. *
  22. */
  23. class  KeepAliveMessageFactoryImpl  implements  KeepAliveMessageFactory {
  24. private   static   final   byte  int_req = - 1 ;
  25. private   static   final   byte  int_rep = - 2 ;
  26. private   static   final  IoBuffer KAMSG_REQ = IoBuffer.wrap( new   byte []{int_req});
  27. private   static   final  IoBuffer KAMSG_REP = IoBuffer.wrap( new   byte []{int_rep});
  28. public  Object getRequest(IoSession session) {
  29. return  KAMSG_REQ.duplicate();
  30. }
  31. public  Object getResponse(IoSession session, Object request) {
  32. return  KAMSG_REP.duplicate();
  33. }
  34. public   boolean  isRequest(IoSession session, Object message) {
  35. if (!(message  instanceof  IoBuffer))
  36. return   false ;
  37. IoBuffer realMessage = (IoBuffer)message;
  38. if (realMessage.limit() !=  1 )
  39. return   false ;
  40. boolean  result = (realMessage.get() == int_req);
  41. realMessage.rewind();
  42. return  result;
  43. }
  44. public   boolean  isResponse(IoSession session, Object message) {
  45. if (!(message  instanceof  IoBuffer))
  46. return   false ;
  47. IoBuffer realMessage = (IoBuffer)message;
  48. if (realMessage.limit() !=  1 )
  49. return   false ;
  50. boolean  result = (realMessage.get() == int_rep);
  51. realMessage.rewind();
  52. return  result;
  53. }
  54. }

有人说:心跳机制的filter只需要服务器端具有即可——这是错误 的,拍着脑袋想一想,看看factory,你就知道了。心跳需要通信两端的实现 。

另外,版本2.0 RC1中,经过测试,当心跳的时间间隔INTERVAL设置为60s(Session的存活时间)的时候心跳会失效,所以最好需要小于60s的间隔。

JAVA NIO异步通信框架MINA选型和使用的几个细节(概述入门,UDP, 心跳)的更多相关文章

  1. Java NIO通信框架在电信领域的实践

    [http://www.codeceo.com/article/java-nio-communication.html]   华为电信软件技术架构演进 Java NIO框架在技术变迁中起到的关键作用 ...

  2. java nio 网络框架

    https://github.com/solq360/common 主要运行在android 平台 解决自动化编/解码,等等.. 模块 解决问题/实现处理 备注 负责人 进度 录音播放 AudioRe ...

  3. java nio 网络框架实现

    maven项目 https://github.com/solq360/common 链式编/解码 链路层链式处理 管道管理socket 多协议处理非常方便 仿netty NioEventLoop 单线 ...

  4. java nio 网络框架实现(转)

    maven项目https://github.com/solq360/common 链式编/解码 链路层链式处理 管道管理socket 多协议处理非常方便 仿netty NioEventLoop 单线程 ...

  5. BIO & NIO & NIO常见框架

    BIO & NIO BIO - Blocking IO - 同步式阻塞式IO --- UDP/TCP NIO - New  IO - 同步式非阻塞式IO AIO  - Asynchronous ...

  6. JAVA NIO 类库的异步通信框架netty和mina

    Netty 和 Mina 我究竟该选择哪个? 根据我的经验,无论选择哪个,都是个正确的选择.两者各有千秋,Netty 在内存管理方面更胜一筹,综合性能也更优.但是,API 变更的管理和兼容性做的不是太 ...

  7. Java NIO框架Mina、Netty、Grizzly介绍与对比(zz)

    Mina:Mina(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用 ...

  8. Java NIO框架Mina、Netty、Grizzly介绍与对比

    Mina:Mina(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用 ...

  9. (转)Java NIO框架Mina、Netty、Grizzly介绍与对比

    转:http://blog.csdn.net/cankykong1/article/details/19937027 Mina: Mina(Multipurpose Infrastructure fo ...

随机推荐

  1. 隐藏Nginx/Apache版本号的安全性与方法

    一.先介绍nginx隐藏版本号的方法. 搭建好nginx或者apache,为了安全起见我们都会隐藏他们的版本号,这边讲的是nginx的版本号,如果你也想隐藏apache的版本号,那请点前面的链接.请看 ...

  2. 《ASP.NET1200例》ListView控件之修改,删除与添加

    aspx <body> <form id="form1" runat="server"> <div> <asp:Lis ...

  3. Greedy:Radar Installation(POJ 1328)

    装雷达 题目大意,就是令在海岸线的(直线)一边是海(y>0),另一边是陆地(y<=0),在海岸线上装雷达,雷达可以覆盖的范围为d,海上有岛,(x,y),问你应该怎么装雷达,才能做到技能雷达 ...

  4. php的socket通信(一)

    什么是TCP/IP.UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域 ...

  5. OSG 初始化为非全屏窗口

    OSG默认的窗口时全屏的,调试的时候不方便. 在网上看到一段代码,可以非全屏显示 int _tmain(int argc, _TCHAR* argv[]){ osgViewer::Viewer vie ...

  6. 删除自带OpenJDK

    1:rpm -qa|grep jdk 查看当前的jdk情况. 2:yum -y remove java java-1.7.0-openjdk* 卸载openjdk,这个过程中因为依赖原因可能会卸载一些 ...

  7. 矩形覆盖(codevs 1101)

    题目描述 Description 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4 ...

  8. Linux底下的第一个C程序

    首先保证你的Linux底下安装了GCC,假如没有安装GCC的话请参考: http://www.cnblogs.com/aspirant/p/3544398.html 假如输入 gcc -v 不再是co ...

  9. svn update 每更新一项就输出一行信息,使用首字符来报告执行的动作 这些字符的含义是:

    A 已添加 D 已删除 U 已更新 C 合并冲突 G 合并成功 例子: [root@ok 资料库]# svn ci -m "" Sending 资料库/简历 Transmittin ...

  10. Redis经验谈

    新浪作为全世界最大的Redis用户,在开发和运维方面有非常多的经验.本文作者来自新浪,希望能为业界提供一些亲身经历,让大家少走弯路. 使用初衷 从2010年上半年起,我们就开始尝试使用Redis,主要 ...