- 浏览: 949414 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
MINA TCP简单通信实例:http://donald-draper.iteye.com/blog/2375297
Mina 过滤链默认构建器:http://donald-draper.iteye.com/blog/2375985
Mina 过滤器定义:http://donald-draper.iteye.com/blog/2376161
引言:
前面一篇文章我们看了一下过滤器定义,先来回顾一下:
IoFilter添加到过滤链时,一般以ReferenceCountingIoFilter包装,添加到过滤链,init方法在添加到过滤链时,由ReferenceCountingIoFilter调用,所以可以在init方法初始化一些共享资源。如果过滤器没有包装成ReferenceCountingIoFilter,init方法将不会调用。然后调用onPreAdd通知过滤器将会添加到过滤连上,当过滤器添加到过滤链上时,所有IoHandler事件和IO请求,将会被过滤器拦截当过滤器添加到过滤链上后,将会调用onPostAdd,如果方法有异常,过滤器在过滤链的链尾,ReferenceCountingIoFilter将调用#destroy方法释放共享资源。过滤器IoFilter,主要是监听会话IoSession相关事件(创建,打开,空闲,异常,关闭,接受数据,发送数据) 及IoSesssion的Write与close事件;过滤器后继NextFilter关注的事件与过滤器IoFilter相同,主要是转发相关事件。WriteRequest是会话IoSession写操作write的包装,内部有一个消息对象用于存放write的内容,一个socket地址,即会话写请求的目的socket地址,一个写请求结果返回值WriteFuture,用于获取会话write消息的操作结果。当一个过滤器从过滤链上移除时,#onPreRemove被调用,用于通知过滤器将从过滤链上移除;如果过滤器从过滤链上移除,所有IoHandler事件和IO请求,过滤器不再拦截;#onPostRemove调用通知过滤器已经从过滤链上移除;移除后,如果过滤器在过滤链的链尾,ReferenceCountingIoFilter将调用#destroy方法释放共享资源。
IoFilter生命周期如下:
inti->onPreAdd->onPostAdd->(拦截IoHandler相关事件:sessionCreated,Opened,Idle,
exceptionCaught,Closed,messageSent,messageReceived;会话相关事件:filterWrite,filterClose)->onPreRemove
->onPostRemove->destroy。
在TCP简单通信实例这篇文章中我们用到的Mina的日志过滤器LoggingFilter如下:
//配置过滤器
今天我们来看一下LoggingFilter。
LoggingFilter拦截IoHandler的sessionCreated事件,将日志输出委托给SessionLog,
然后将相关事件传递给过滤器后继,拦截sessionOpened,sessionClosed,filterClose事件思路基本相同。对于sessionIdle,messageSent,messageReceived,filterWrite先判断会话log的info级别是否开启,开启则输出相应事件日志。上面这些事件的日志级别都是Info;exceptionCaught则先判断会话log的warn级别是否开启,开启则输出相应事件日志。
再来看SessionLog:
在TCP简单通信实例这篇文章中我们创建过一个测试的过滤器TestFilter,通过ReferenceCountingFilter包装添加
过滤链上:
在前面过滤器的文章我们也提到过ReferenceCountingFilter,下面我们再来看一下ReferenceCountingFilter
一个过滤器可以多次添加到过滤链上,如何保证过滤器第一次添加到过滤链上时,初始化过滤器,完全从过滤链上移除时,销毁过滤器,释放资源?这就是ReferenceCountingIoFilter的作用,ReferenceCountingIoFilter同时也是一个过滤器,内部一个count用于记录过滤器filter添加到过滤链上的次数,即过滤链上存在filter的个数,一个filter,即ReferenceCountingIoFilter包装的过滤器,触发IoHandler和IoSession的相关事件,直接交给包装的内部filter处理。
总结:
LoggingFilter拦截IoHandler的sessionCreated事件,将日志输出委托给SessionLog,然后将相关事件传递给过滤器后继,拦截sessionOpened,sessionClosed,
filterClose事件思路基本相同。对于sessionIdle,messageSent,messageReceived,
filterWrite先判断会话log的info级别是否开启,开启则输出相应事件日志。上面这些事件的日志级别都是Info;exceptionCaught则先判断会话log的warn级别是否开启,开启则输出相应
事件日志。
一个过滤器可以多次添加到过滤链上,ReferenceCountingIoFilter用于保证过滤器第一次添加到过滤链上时,初始化过滤器,完全从过滤链上移除时,销毁过滤器,释放资源;ReferenceCountingIoFilter内部一个count用于记录包装过滤器filter添加到过滤链上的次数,即过滤链上存在filter的个数,一个filter,即ReferenceCountingIoFilter包装的过滤器,ReferenceCountingIoFilter触发IoHandler和IoSession的相关事件,直接交给包装的内部filter处理。
Mina 过滤链默认构建器:http://donald-draper.iteye.com/blog/2375985
Mina 过滤器定义:http://donald-draper.iteye.com/blog/2376161
引言:
前面一篇文章我们看了一下过滤器定义,先来回顾一下:
IoFilter添加到过滤链时,一般以ReferenceCountingIoFilter包装,添加到过滤链,init方法在添加到过滤链时,由ReferenceCountingIoFilter调用,所以可以在init方法初始化一些共享资源。如果过滤器没有包装成ReferenceCountingIoFilter,init方法将不会调用。然后调用onPreAdd通知过滤器将会添加到过滤连上,当过滤器添加到过滤链上时,所有IoHandler事件和IO请求,将会被过滤器拦截当过滤器添加到过滤链上后,将会调用onPostAdd,如果方法有异常,过滤器在过滤链的链尾,ReferenceCountingIoFilter将调用#destroy方法释放共享资源。过滤器IoFilter,主要是监听会话IoSession相关事件(创建,打开,空闲,异常,关闭,接受数据,发送数据) 及IoSesssion的Write与close事件;过滤器后继NextFilter关注的事件与过滤器IoFilter相同,主要是转发相关事件。WriteRequest是会话IoSession写操作write的包装,内部有一个消息对象用于存放write的内容,一个socket地址,即会话写请求的目的socket地址,一个写请求结果返回值WriteFuture,用于获取会话write消息的操作结果。当一个过滤器从过滤链上移除时,#onPreRemove被调用,用于通知过滤器将从过滤链上移除;如果过滤器从过滤链上移除,所有IoHandler事件和IO请求,过滤器不再拦截;#onPostRemove调用通知过滤器已经从过滤链上移除;移除后,如果过滤器在过滤链的链尾,ReferenceCountingIoFilter将调用#destroy方法释放共享资源。
IoFilter生命周期如下:
inti->onPreAdd->onPostAdd->(拦截IoHandler相关事件:sessionCreated,Opened,Idle,
exceptionCaught,Closed,messageSent,messageReceived;会话相关事件:filterWrite,filterClose)->onPreRemove
->onPostRemove->destroy。
在TCP简单通信实例这篇文章中我们用到的Mina的日志过滤器LoggingFilter如下:
//配置过滤器
DefaultIoFilterChainBuilder defaultIoFilterChainBuilder = acceptor.getFilterChain(); LoggingFilter loggingFilter = new LoggingFilter(); defaultIoFilterChainBuilder.addLast("loggingFilter", loggingFilter);
今天我们来看一下LoggingFilter。
package org.apache.mina.filter; import org.apache.mina.common.IdleStatus; import org.apache.mina.common.IoFilterAdapter; import org.apache.mina.common.IoSession; import org.apache.mina.util.SessionLog; import org.slf4j.Logger; /** * Logs all MINA protocol events to {@link Logger}. * * @author The Apache Directory Project (mina-dev@directory.apache.org) * @version $Rev$, $Date$ * * @see SessionLog */ public class LoggingFilter extends IoFilterAdapter { /** * Session attribute key: prefix string */ public static final String PREFIX = SessionLog.PREFIX; /** * Session attribute key: {@link Logger} */ public static final String LOGGER = SessionLog.LOGGER; /** * Creates a new instance. */ public LoggingFilter() { } //拦截IoHandler的sessionCreated事件,将日志输出委托给SessionLog, //然后将相关事件传递给过滤器后继,拦截sessionOpened,sessionClosed思路基本相同 public void sessionCreated(NextFilter nextFilter, IoSession session) { SessionLog.info(session, "CREATED"); nextFilter.sessionCreated(session); } public void sessionOpened(NextFilter nextFilter, IoSession session) { SessionLog.info(session, "OPENED"); nextFilter.sessionOpened(session); } public void sessionClosed(NextFilter nextFilter, IoSession session) { SessionLog.info(session, "CLOSED"); nextFilter.sessionClosed(session); } public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) { //先判断会话日志Info级别是否开启 if (SessionLog.isInfoEnabled(session)) { SessionLog.info(session, "IDLE: " + status); } nextFilter.sessionIdle(session, status); } public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) { if (SessionLog.isWarnEnabled(session)) { SessionLog.warn(session, "EXCEPTION:", cause); } nextFilter.exceptionCaught(session, cause); } public void messageReceived(NextFilter nextFilter, IoSession session, Object message) { if (SessionLog.isInfoEnabled(session)) { SessionLog.info(session, "RECEIVED: " + message); } nextFilter.messageReceived(session, message); } public void messageSent(NextFilter nextFilter, IoSession session, Object message) { if (SessionLog.isInfoEnabled(session)) { SessionLog.info(session, "SENT: " + message); } nextFilter.messageSent(session, message); } public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) { if (SessionLog.isInfoEnabled(session)) { SessionLog.info(session, "WRITE: " + writeRequest); } nextFilter.filterWrite(session, writeRequest); } public void filterClose(NextFilter nextFilter, IoSession session) throws Exception { SessionLog.info(session, "CLOSE"); nextFilter.filterClose(session); } }
LoggingFilter拦截IoHandler的sessionCreated事件,将日志输出委托给SessionLog,
然后将相关事件传递给过滤器后继,拦截sessionOpened,sessionClosed,filterClose事件思路基本相同。对于sessionIdle,messageSent,messageReceived,filterWrite先判断会话log的info级别是否开启,开启则输出相应事件日志。上面这些事件的日志级别都是Info;exceptionCaught则先判断会话log的warn级别是否开启,开启则输出相应事件日志。
再来看SessionLog:
package org.apache.mina.util; import org.apache.mina.common.IoSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; //从包引入来看MINA默认用slf4j日志组件 /** * Provides utility methods to log protocol-specific messages. * <p> * Set {@link #PREFIX} and {@link #LOGGER} session attributes * to override prefix string and logger. * * @author The Apache Directory Project (mina-dev@directory.apache.org) * @version $Rev$, $Date$ * */ public class SessionLog { /** * Session attribute key: prefix string */ public static final String PREFIX = SessionLog.class.getName() + ".prefix"; /** * Session attribute key: {@link Logger} */ public static final String LOGGER = SessionLog.class.getName() + ".logger"; //获取会话IoHandler类型 private static Class getClass(IoSession session) { return session.getHandler().getClass(); } //Debug输出,如果会话日志开启debug级别,则输出debug日志 public static void debug(IoSession session, String message) { Logger log = getLogger(session); if (log.isDebugEnabled()) { log.debug(String.valueOf(session.getAttribute(PREFIX)) + message); } } public static void debug(IoSession session, String message, Throwable cause) { Logger log = getLogger(session); if (log.isDebugEnabled()) { log.debug(String.valueOf(session.getAttribute(PREFIX)) + message, cause); } } //获取会话日志 private static Logger getLogger(IoSession session) { Logger log = (Logger) session.getAttribute(LOGGER); if (log == null) { //如果会话日志为空,则从LoggerFactory获取Logger log = LoggerFactory.getLogger(getClass(session)); String prefix = (String) session.getAttribute(PREFIX); if (prefix == null) { prefix = "[" + session.getRemoteAddress() + "] "; session.setAttribute(PREFIX, prefix); } //将日志log,添加到会话中 session.setAttribute(LOGGER, log); } return log; } //判断log的debug级别是否开启 public static boolean isDebugEnabled(IoSession session) { return getLogger(session).isDebugEnabled(); } /*下面的info,warn,error与debug的思想是一致的这里不再说 */ public static void info(IoSession session, String message) { Logger log = getLogger(session); if (log.isInfoEnabled()) { log.info(String.valueOf(session.getAttribute(PREFIX)) + message); } } public static void info(IoSession session, String message, Throwable cause) { Logger log = getLogger(session); if (log.isInfoEnabled()) { log.info(String.valueOf(session.getAttribute(PREFIX)) + message, cause); } } public static void warn(IoSession session, String message) { Logger log = getLogger(session); if (log.isWarnEnabled()) { log.warn(String.valueOf(session.getAttribute(PREFIX)) + message); } } public static void warn(IoSession session, String message, Throwable cause) { Logger log = getLogger(session); if (log.isWarnEnabled()) { log.warn(String.valueOf(session.getAttribute(PREFIX)) + message, cause); } } public static void error(IoSession session, String message) { Logger log = getLogger(session); if (log.isErrorEnabled()) { log.error(String.valueOf(session.getAttribute(PREFIX)) + message); } } public static void error(IoSession session, String message, Throwable cause) { Logger log = getLogger(session); if (log.isErrorEnabled()) { log.error(String.valueOf(session.getAttribute(PREFIX)) + message, cause); } } public static boolean isInfoEnabled(IoSession session) { return getLogger(session).isInfoEnabled(); } public static boolean isWarnEnabled(IoSession session) { return getLogger(session).isWarnEnabled(); } public static boolean isErrorEnabled(IoSession session) { return getLogger(session).isErrorEnabled(); } }
在TCP简单通信实例这篇文章中我们创建过一个测试的过滤器TestFilter,通过ReferenceCountingFilter包装添加
过滤链上:
TestFilter testFilter = new TestFilter(); ReferenceCountingFilter referenceCountingFilter = new ReferenceCountingFilter(testFilter); defaultIoFilterChainBuilder.addLast("testFilter",referenceCountingFilter);
在前面过滤器的文章我们也提到过ReferenceCountingFilter,下面我们再来看一下ReferenceCountingFilter
package org.apache.mina.filter; import org.apache.mina.common.IdleStatus; import org.apache.mina.common.IoFilter; import org.apache.mina.common.IoFilterChain; import org.apache.mina.common.IoSession; /** * An {@link IoFilter}s wrapper that keeps track of the number of usages of this filter and will call init/destroy * when the filter is not in use. *ReferenceCountingIoFilter用于包装过滤器,用于记录过滤器的使用量, 当过滤器添加到过滤链上时,调用过滤器的init方法,从过滤链上移除时,调用过滤器的destroy方法。 * @author The Apache Directory Project (mina-dev@directory.apache.org) * @version $Rev$, $Date$ */ public class ReferenceCountingIoFilter implements IoFilter { private final IoFilter filter;//包装的过滤器 private int count = 0;//过滤器使用计数器 public ReferenceCountingIoFilter(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 { //no-op, will destroy on-demand in post-remove if count == 0 } public void onPostAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { filter.onPostAdd(parent, name, nextFilter); } public synchronized void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { if (0 == count) { //当过滤器首次添加到过滤链上时,调用过滤器的init方法。 filter.init(); ++count; } filter.onPreAdd(parent, name, nextFilter); } public void onPreRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { filter.onPreRemove(parent, name, nextFilter); } public synchronized void onPostRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { filter.onPostRemove(parent, name, nextFilter); --count; //当过滤器从过滤链上完全移除时,调用过滤器的destroy方法。 if (0 == count) { filter.destroy(); } } public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception { filter.exceptionCaught(nextFilter, session, cause); } public void filterClose(NextFilter nextFilter, IoSession session) throws Exception { filter.filterClose(nextFilter, session); } public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { filter.filterWrite(nextFilter, session, writeRequest); } public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { filter.messageReceived(nextFilter, session, message); } public void messageSent(NextFilter nextFilter, IoSession session, Object message) throws Exception { filter.messageSent(nextFilter, session, message); } public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { filter.sessionClosed(nextFilter, session); } public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { filter.sessionCreated(nextFilter, session); } public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception { filter.sessionIdle(nextFilter, session, status); } public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { filter.sessionOpened(nextFilter, session); } }
一个过滤器可以多次添加到过滤链上,如何保证过滤器第一次添加到过滤链上时,初始化过滤器,完全从过滤链上移除时,销毁过滤器,释放资源?这就是ReferenceCountingIoFilter的作用,ReferenceCountingIoFilter同时也是一个过滤器,内部一个count用于记录过滤器filter添加到过滤链上的次数,即过滤链上存在filter的个数,一个filter,即ReferenceCountingIoFilter包装的过滤器,触发IoHandler和IoSession的相关事件,直接交给包装的内部filter处理。
总结:
LoggingFilter拦截IoHandler的sessionCreated事件,将日志输出委托给SessionLog,然后将相关事件传递给过滤器后继,拦截sessionOpened,sessionClosed,
filterClose事件思路基本相同。对于sessionIdle,messageSent,messageReceived,
filterWrite先判断会话log的info级别是否开启,开启则输出相应事件日志。上面这些事件的日志级别都是Info;exceptionCaught则先判断会话log的warn级别是否开启,开启则输出相应
事件日志。
一个过滤器可以多次添加到过滤链上,ReferenceCountingIoFilter用于保证过滤器第一次添加到过滤链上时,初始化过滤器,完全从过滤链上移除时,销毁过滤器,释放资源;ReferenceCountingIoFilter内部一个count用于记录包装过滤器filter添加到过滤链上的次数,即过滤链上存在filter的个数,一个filter,即ReferenceCountingIoFilter包装的过滤器,ReferenceCountingIoFilter触发IoHandler和IoSession的相关事件,直接交给包装的内部filter处理。
发表评论
-
Mina 报文连接器(NioDatagramConnector)
2017-06-14 08:46 1336Mina 抽象Polling连接器(A ... -
Mina 报文监听器NioDatagramAcceptor二(发送会话消息等)
2017-06-13 16:01 1487Mina 报文监听器NioDatagramAcceptor一( ... -
Mina 报文监听器NioDatagramAcceptor一(初始化,Io处理器)
2017-06-13 09:51 2499Mina Io监听器接口定义及抽象实现:http://dona ... -
Mina 报文通信简单示例
2017-06-12 09:01 2481MINA TCP简单通信实例:http://donald-dr ... -
Mina socket连接器(NioSocketConnector)
2017-06-12 08:37 4638Mina 抽象Polling连接器(AbstractPolli ... -
Mina 抽象Polling连接器(AbstractPollingIoConnector)
2017-06-11 21:29 958Mina 连接器接口定义及抽象实现(IoConnector ) ... -
Mina 连接器接口定义及抽象实现(IoConnector )
2017-06-11 13:46 1769Mina IoService接口定义及抽象实现:http:// ... -
Mina socket监听器(NioSocketAcceptor)
2017-06-09 08:44 3331Mina IoService接口定义及抽象实现:http:// ... -
Mina 抽象polling监听器
2017-06-08 22:32 707Mina Io监听器接口定义及抽象实现:http://dona ... -
Mina Io监听器接口定义及抽象实现
2017-06-07 13:02 1293Mina IoService接口定义及抽象实现:http:// ... -
Mina IoService接口定义及抽象实现
2017-06-06 23:44 1122Mina IoHandler接口定义:http://donal ... -
Mina Nio会话(Socket,DataGram)
2017-06-06 12:53 1142Mina Socket会话配置:http://donald-d ... -
Mina 抽象Io会话
2017-06-05 22:45 966Mina Io会话接口定义:http://donald-dra ... -
Mina Io会话接口定义
2017-06-04 23:15 1093Mina Nio处理器:http://donald-drape ... -
Mina Nio处理器
2017-06-04 22:19 690Mina Io处理器抽象实现:http://donald-dr ... -
Mina Io处理器抽象实现
2017-06-03 23:52 1081Mina 过滤链抽象实现:http://donald-drap ... -
Mina IoHandler接口定义
2017-06-01 21:30 1667Mina 过滤链抽象实现:http://donald-drap ... -
MINA 多路复用协议编解码器工厂二(多路复用协议解码器)
2017-06-01 12:52 2191MINA 多路复用协议编解码器工厂一(多路复用协议编码器): ... -
MINA 多路复用协议编解码器工厂一(多路复用协议编码器)
2017-05-31 22:22 1790MINA 多路分离解码器实例:http://donald-dr ... -
Mina 累计协议解码器
2017-05-31 00:09 1151MINA 编解码器实例:http://donald-drape ...
相关推荐
NULL 博文链接:https://wen866595.iteye.com/blog/1154137
mina socket 使用详解,这个文档简单易懂,是初学者的大大福音。
mina自定义编码器-自行做会话累积。apache mina编码器
本资源包含两个 pdf 文档,一本根据官方最新文档 ...第十二章:日志过滤器 第十三章:调试 第十四章:状态机 第十五章:代理 第十六章:JMX 集成 第十七章:Spring 集成
许多刚接触mina的朋友,对于mina的编解码器的编写很迷惑.希望这个文档可以帮助朋友们少走弯路。 资源中是一个比较典型的编解码器写法。生成了可执行文件。并对编解码器的代码有详细注释。
mina编码器详解,mina编码器详解很详细哦
mina-filter-compression-2.0.7.jar,mina 过滤器jar包,核心包之一
该压缩包中有两个文件夹mina_server和minaclient,先启动mina_server,然后启动minaclient即可运行
mina框架自定义解编码器的小例子,里面包含所需的Jar,请使用JDK1.7,若无法运行,请留言
Mina2.0快速入门与源码剖析(个人经验文档)
里面包含mina2.0的api(英文)和mina自学手册,还有mina的开发指导
mina的使用初步入门mina的使用初步入门mina的使用初步入门
mina自定义编码器-固定位置指定消息的长度。apache mina
NULL 博文链接:https://thb143.iteye.com/blog/1538083
mina连接,mina心跳连接,mina断线重连。其中客户端可直接用在android上。根据各方参考资料,经过自己的理解弄出来的。CSDN的资源分太难得了。
两个mina开发文档,含有所有的mina的简单开发案例与教程
Mina 2.0快速入门与源码解析 很适合初学者使用!!!
mina-core-2.0.0-M6.jar mina-example-2.0.0-M6.jar mina-filter-codec-netty-2.0.0-M6.jar mina-filter-compression-2.0.0-M6.jar mina-integration-beans-2.0.0-M6.jar mina-integration-jmx-2.0.0-M6.jar mina-...
服务器端模拟SFS2X的一些实用功能对mina框架作了一定的封装,使用起来己经和SFS2X没有 太多的区别,但客户端只能使用mina组件(也就是说只能...客户端可以模拟多个实例与服务器连接,方便测试,感觉mina的性能还是不错的