二、执行流程
由上至下分别是IoHandler、IoFilter、IoProcessor、IoService。
IoHandler:负责业务逻辑的处理,即数据的接收和发送。
IoFilter:定义一组连接器,包括日志输出、黑名单过滤、数据的编解码。
IoProcessor:检查是否有数据在通道上读写。
IoService:负责套接字的建立,拥有自己的selector,监听是否有连接建立。
mina框架客户端与服务器端的执行流程一致,区别是IoService的client端实现的是IoConnector,server端是IoAcceptor。
三、客户端创建步骤
1、创建IoService
IoConnector connector = new NioSocketConnector();
connector.setConnectTimeoutMillis(30000);
2、注册过滤器
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new
TextLineCodecFactory(Charset.forName("UTF-8"))));
3、注册IoHandler到IoService
connector.setHandler(new IoHandlerAdapter(){ ... });
4、绑定套接字,建立连接
connector.connect(new InetSocketAddress("localhost", 1000));
四、服务器端创建步骤
1、创建IoService
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);//读写通道在10秒内无任何操作进入空闲状态。
2、注册过滤器
acceptor.getFilterChain().addLast("codec", new ProtocolFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
3、注册IoHandler到IoService
acceptor.setHandler(new IoHandlerAdapter(){ ... });
4、绑定套接字
acceptor.bind(new InetSocketAddress(1000));
五、IoHandler详解
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的类抛出异常时调用。
注意:一般情况下,很少有人直接实现IoHandler接口,而是用它的实现类IoHandlerAdapter,这样就不用覆盖所有的7个方法。
六、IoSession详解
setAttribute(Object key, Object value)和getAttribute(Object key):设置/获取用户定义的属性。将该属性与session联系起来,方便以后处理用户请求时使用。
getRemoteAddress():获取远程客户端地址。
getId():获取session的id。
getCreationTime():获取创建时间。
getLastIoTime():获取上次I/O时间。
getConfig():获取配置信息。
write(Object message):将数据发送到客户端。
close():关闭session。
七、关于多会话管理的一些思考
在开发的过程中难免会遇到一个客户端连接多个服务端,或者多个客户端连接一个服务端的情况。那么我们该怎么控制好这些通信线路呢?其实很简单,只要保存好IoSession就可以了,如果觉得IoSession接口比较占内存的话,可以通过调用session.getId()来获取sessionId。如何获取所有的会话呢?我们可以调用connector或acceptor的getManagedSessions()方法来获取所有管理着的会话。