JAVA NIO异步通信框架MINA选型和使用的几个细节(概述入门,UDP, 心跳)
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 服务器端
- NioDatagramAcceptor acceptor = new NioDatagramAcceptor();
- acceptor.setHandler(new MyIoHandlerAdapter()); //你的业务处理,最简单的,可以extends IoHandlerAdapter
- DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
- chain.addLast("keep-alive" , new HachiKeepAliveFilterInMina()); //心跳
- chain.addLast("toMessageTyep" , new MyMessageEn_Decoder());
- //将传输的数据转换成你的业务数据格式。比如下面的是将数据转换成一行行的文本
- //acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
- chain.addLast("logger" , new LoggingFilter());
- DatagramSessionConfig dcfg = acceptor.getSessionConfig();
- dcfg.setReuseAddress(true );
- acceptor.bind(new InetSocketAddress(ClusterContext.getHeartBeatPort()));
1.2 客户端
- NioDatagramConnector connector = new NioDatagramConnector();
- connector.setConnectTimeoutMillis(60000L);
- connector.setConnectTimeoutCheckInterval(10000 );
- connector.setHandler(handler);
- DefaultIoFilterChainBuilder chain = connector.getFilterChain();
- chain.addLast("keep-alive" , new HachiKeepAliveFilterInMina()); //心跳
- chain.addLast("toMessageTyep" , new MyMessageEn_Decoder());
- chain.addLast("logger" , new LoggingFilter());
- ConnectFuture connFuture = connector.connect(new InetSocketAddress( "10.1.1.1" , 8001 ));
- connFuture.awaitUninterruptibly();
- IoSession session = connFuture.getSession();
- //发送消息长整型 1000
- IoBuffer buffer = IoBuffer.allocate(8 );
- buffer.putLong(1000 );
- buffer.flip();
- session.write(buffer);
- //关闭连接
- session.getCloseFuture().awaitUninterruptibly();
- connector.dispose();
2. 超时的几个经验总结:
udp session默认是60秒钟超时,此时状态为closing,数据就发不出去了。
Session的接口是IoSession,udp的最终实现是NioSession。如果交互在60秒内不能处理完成,就需要使用Keep-alive机制,即心跳机制。
3. 心跳 机制
在代码中已经使用了心跳机制,是通过mina的filter实现的,mina自身带的心跳机制好处在于,它附加了处理,让心跳消息不会传到业务层,在底层就完成了。
在上面代码实现中的HachiKeepAliveFilterInMina如下:
- public class HachiKeepAliveFilterInMina extends KeepAliveFilter {
- private static final int INTERVAL = 30 ; //in seconds
- private static final int TIMEOUT = 10 ; //in seconds
- public HachiKeepAliveFilterInMina(KeepAliveMessageFactory messageFactory) {
- super (messageFactory, IdleStatus.BOTH_IDLE, new ExceptionHandler(), INTERVAL, TIMEOUT);
- }
- public HachiKeepAliveFilterInMina() {
- super ( new KeepAliveMessageFactoryImpl(), IdleStatus.BOTH_IDLE, new ExceptionHandler(), INTERVAL, TIMEOUT);
- this .setForwardEvent( false ); //此消息不会继续传递,不会被业务层看见
- }
- }
- class ExceptionHandler implements KeepAliveRequestTimeoutHandler {
- public void keepAliveRequestTimedOut(KeepAliveFilter filter, IoSession session) throws Exception {
- System.out.println("Connection lost, session will be closed" );
- session.close(true );
- }
- }
- /**
- * 继承于KeepAliveMessageFactory,当心跳机制启动的时候,需要该工厂类来判断和定制心跳消息
- * @author Liu Liu
- *
- */
- class KeepAliveMessageFactoryImpl implements KeepAliveMessageFactory {
- private static final byte int_req = - 1 ;
- private static final byte int_rep = - 2 ;
- private static final IoBuffer KAMSG_REQ = IoBuffer.wrap( new byte []{int_req});
- private static final IoBuffer KAMSG_REP = IoBuffer.wrap( new byte []{int_rep});
- public Object getRequest(IoSession session) {
- return KAMSG_REQ.duplicate();
- }
- public Object getResponse(IoSession session, Object request) {
- return KAMSG_REP.duplicate();
- }
- public boolean isRequest(IoSession session, Object message) {
- if (!(message instanceof IoBuffer))
- return false ;
- IoBuffer realMessage = (IoBuffer)message;
- if (realMessage.limit() != 1 )
- return false ;
- boolean result = (realMessage.get() == int_req);
- realMessage.rewind();
- return result;
- }
- public boolean isResponse(IoSession session, Object message) {
- if (!(message instanceof IoBuffer))
- return false ;
- IoBuffer realMessage = (IoBuffer)message;
- if (realMessage.limit() != 1 )
- return false ;
- boolean result = (realMessage.get() == int_rep);
- realMessage.rewind();
- return result;
- }
- }
有人说:心跳机制的filter只需要服务器端具有即可——这是错误 的,拍着脑袋想一想,看看factory,你就知道了。心跳需要通信两端的实现 。
另外,版本2.0 RC1中,经过测试,当心跳的时间间隔INTERVAL设置为60s(Session的存活时间)的时候心跳会失效,所以最好需要小于60s的间隔。
JAVA NIO异步通信框架MINA选型和使用的几个细节(概述入门,UDP, 心跳)的更多相关文章
- Java NIO通信框架在电信领域的实践
[http://www.codeceo.com/article/java-nio-communication.html] 华为电信软件技术架构演进 Java NIO框架在技术变迁中起到的关键作用 ...
- java nio 网络框架
https://github.com/solq360/common 主要运行在android 平台 解决自动化编/解码,等等.. 模块 解决问题/实现处理 备注 负责人 进度 录音播放 AudioRe ...
- java nio 网络框架实现
maven项目 https://github.com/solq360/common 链式编/解码 链路层链式处理 管道管理socket 多协议处理非常方便 仿netty NioEventLoop 单线 ...
- java nio 网络框架实现(转)
maven项目https://github.com/solq360/common 链式编/解码 链路层链式处理 管道管理socket 多协议处理非常方便 仿netty NioEventLoop 单线程 ...
- BIO & NIO & NIO常见框架
BIO & NIO BIO - Blocking IO - 同步式阻塞式IO --- UDP/TCP NIO - New IO - 同步式非阻塞式IO AIO - Asynchronous ...
- JAVA NIO 类库的异步通信框架netty和mina
Netty 和 Mina 我究竟该选择哪个? 根据我的经验,无论选择哪个,都是个正确的选择.两者各有千秋,Netty 在内存管理方面更胜一筹,综合性能也更优.但是,API 变更的管理和兼容性做的不是太 ...
- Java NIO框架Mina、Netty、Grizzly介绍与对比(zz)
Mina:Mina(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用 ...
- Java NIO框架Mina、Netty、Grizzly介绍与对比
Mina:Mina(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用 ...
- (转)Java NIO框架Mina、Netty、Grizzly介绍与对比
转:http://blog.csdn.net/cankykong1/article/details/19937027 Mina: Mina(Multipurpose Infrastructure fo ...
随机推荐
- Kth Largest Element in an Array
Find K-th largest element in an array. Notice You can swap elements in the array Example In array [9 ...
- 毫秒数转换为指定格式日期的js代码
var format = function(time, format){ var t = new Date(time); var tf = function(i){return (i < 10 ...
- Code(poj 1850)
大致题意:(与POJ1496基本一致) 输出某个str字符串在字典中的位置,由于字典是从a=1开始的,因此str的位置值就是 在str前面所有字符串的个数 +1 规定输入的字符串必须是升序排列.不降序 ...
- Jam的计数法(codevs 1140)
题目描述 Description Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用 ...
- Linux设置IP
进入 vi /etc/sysconfig/network-scripts/ifcfg-eth0 root # ifconfig eth0 192.168.22.232 root # route ad ...
- 手机/平板 连接局域网访问局域网电脑Web服务器进行移动端页面测试
1.开启本地服务器(我用的是XAMPP) 2.查看本机IP Mac:点击左上角的苹果标志,选择系统偏好设置,弹出系统偏好设置面板-----点击网络,选择高级,切换到tcp/ip 选项卡 会看到本机IP ...
- 在有EditText控件的AlertDialog对话框中自动弹出输入法
我们先回顾一下创建AlertDialog的一般步骤. 一 inflate AlertDialog的布局文件 例如,其中dlg就是我们的布局文件. View layout = LayoutIn ...
- Mac OS X 上的安装haskell开发环境
到haskell官方下载haskell的工具包: https://downloads.haskell.org/~platform/2014.2.0.0/Haskell%20Platform%20201 ...
- PHP 判断数组里的值是否有存在
一维数组检测<?php $a = array('as','ddf','ddf','as','qwe','wer','ert'); $res = array_unique($a); var_d ...
- GRE学习日志
发现开博客园真的很有督促作用,今天也顺便开个GRE学习日志吧 2015-02-09:单词 2015-02-10:单词 2015-02-11:单词 2015-03-02:阅读 2015-03-04:阅读 ...