最近用mina写客户端一点心得,分享下,如果有不对的地方,希望留言更正。
编码、解码工厂就不写了,网上有很多。
private static NioSocketConnector connector ; private static IoSession session; public static IoSession getIoSession(){ return session; } public static NioSocketConnector getConnector(){ if(null==connector){ // 创建非阻塞的server端的Socket连接 connector = new NioSocketConnector(); } return connector; } public static void clientStart(){ // 创建客户端连接器 final NioSocketConnector connector = getConnector(); //添加消息工厂(编码、解码工厂) connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MsgProtocol())); //===============心跳============ ClientKeepAliveFactoryImpl cka = new ClientKeepAliveFactoryImpl(); KeepAliveFilter kaf = new KeepAliveFilter(cka,IdleStatus.READER_IDLE,KeepAliveRequestTimeoutHandler.CLOSE);//实例化一个 KeepAliveFilter 过滤器 kaf.setForwardEvent(true);// 继续调用 IoHandlerAdapter 中的 sessionIdle时间 kaf.setRequestInterval(10); //设置当连接的读取通道空闲的时候,心跳包请求时间间隔 kaf.setRequestTimeout(5); //设置心跳包请求后 等待反馈超时时间。 超过该时间后则调用KeepAliveRequestTimeoutHandler.CLOSE connector.getFilterChain().addLast("heart",kaf);//该过滤器加入到整个通信的过滤链中 //==============心跳--End=========== //==============LOG日志============= LoggingFilter loggingFilter = new LoggingFilter(); loggingFilter.setMessageReceivedLogLevel(LogLevel.INFO); loggingFilter.setMessageSentLogLevel(LogLevel.INFO); connector.getFilterChain().addLast("logger", loggingFilter); //=============LOG日志--End============= connector.getSessionConfig().setReceiveBufferSize(2048*5000);//接收缓冲区1M connector.setConnectTimeoutMillis(30000); // 设置连接超时 connector.setHandler(new ClientIoHandler());// 设置消息处理器 // ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",9999));// 建立连接 //=============添加监控,断线重连============ connector.setDefaultRemoteAddress(new InetSocketAddress("localhost",6900)); connector.addListener(new IoListener(){ @Override public void sessionDestroyed(IoSession arg)throws Exception{ for (;;) { try { Thread.sleep(5000); ConnectFuture future = connector.connect(); future.awaitUninterruptibly();// 等待连接创建完成 session = future.getSession(); if (session.isConnected()) { System.out.println("断线重连[" + connector.getDefaultRemoteAddress().getHostName() + ":" + connector.getDefaultRemoteAddress().getPort() + "]成功"); break; } } catch (Exception e) { System.out.println("重连服务器登录失败,5秒再连接一次:" + e.getMessage()); } } } }); //==================断线重连--End================== for(;;){ try { ConnectFuture future = connector.connect(); future.awaitUninterruptibly(); session = future.getSession(); break; } catch (Exception e) { try { System.out.println("连接服务端失败--等待重新连接服务器" + e.getMessage()); Thread.sleep(5000);// 连接失败后,重连间隔5s } catch (InterruptedException e1) { e1.printStackTrace(); } } } }
public class ClientKeepAliveFactoryImpl implements KeepAliveMessageFactory {
@Override
public Object getRequest(IoSession session) {
session.write("心跳");
return null;
}
@Override
public Object getResponse(IoSession arg0, Object arg1) {
return null;
}
@Override
public boolean isRequest(IoSession arg0, Object arg1) {
return false;
}
@Override
public boolean isResponse(IoSession arg0, Object arg1) {
return false;
}
public class IoListener implements IoServiceListener{
@Override
public void serviceActivated(IoService arg0) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void serviceDeactivated(IoService arg0) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void serviceIdle(IoService arg0, IdleStatus arg1) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionCreated(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionDestroyed(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionClosed(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
}
}