mina自带了心跳包机制,我是每隔15秒发送一次心跳包,若30秒内没有收到,则认为超时。
网络连接的主题函数是:
/**
* 30秒后超时
*/
private static final int IDELTIMEOUT = 30;
/**
* 15秒发送一次心跳包
*/
private static final int HEARTBEATRATE = 15;
new Thread(new Runnable() {
@Override
public void run() {
<pre name="code" class="java">while(true) {
try {
Thread.sleep(3000);
connector.setConnectTimeoutMillis(30000); //设置连接超时
connector.getFilterChain().addLast(
"codec",
new ProtocolCodecFilter(new ToServerProtocolCodecFactory()));
connector.getSessionConfig().setReadBufferSize(1024);
connector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, IDELTIMEOUT);
/** 主角登场 */
KeepAliveMessageFactory heartBeatFactory = new KeepAliveMessageFactoryImpl();
KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory);
/** 是否回发 */
heartBeat.setForwardEvent(true);
/** 发送频率 */
heartBeat.setRequestInterval(HEARTBEATRATE);
//connector.getSessionConfig().setKeepAlive(true);
connector.getFilterChain().addLast("heartbeat", heartBeat);
/****************************/
connector.setHandler(dataHandler);
// 这里是异步操作 连接后立即返回
ConnectFuture future = connector.connect(new InetSocketAddress(
IP, PORT));
future.awaitUninterruptibly();// 等待连接创建完成
session = future.getSession();
if(session.isConnected()) {
break;
}
} catch (Exception e) {
}
}<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
} }).start();
private static class KeepAliveMessageFactoryImpl implements KeepAliveMessageFactory {
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.filter.keepalive.KeepAliveMessageFactory#getRequest
* (org.apache.mina.core.session.IoSession)
*/
@Override
public Object getRequest(IoSession session) {
// i++;
// Log.d("session",i+"");
// if (i > 5) {
// try {
// Log.d("session","睡眠");
// Thread.sleep(40000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
return heartbeatrequest;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.filter.keepalive.KeepAliveMessageFactory#getResponse
* (org.apache.mina.core.session.IoSession, java.lang.Object)
*/
@Override
public Object getResponse(IoSession session, Object request) {
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.filter.keepalive.KeepAliveMessageFactory#isRequest
* (org.apache.mina.core.session.IoSession, java.lang.Object)
*/
@Override
public boolean isRequest(IoSession session, Object message) {
return false;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.mina.filter.keepalive.KeepAliveMessageFactory#isResponse
* (org.apache.mina.core.session.IoSession, java.lang.Object)
*/
@Override
public boolean isResponse(IoSession session, Object message) {
if (message instanceof HEARTBEATRESPONSE) {
Log.d("session","是响应心跳包");
return true;
}
return false;
}
}
/***
* @ClassName: KeepAliveRequestTimeoutHandlerImpl
* @Description: 当心跳超时时的处理,也可以用默认处理 这里like
*/
private static class KeepAliveRequestTimeoutHandlerImpl implements KeepAliveRequestTimeoutHandler {
/*
* (non-Javadoc)
*
* @seeorg.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler#
* keepAliveRequestTimedOut
* (org.apache.mina.filter.keepalive.KeepAliveFilter,
* org.apache.mina.core.session.IoSession)
*/
@Override
public void keepAliveRequestTimedOut(KeepAliveFilter filter, IoSession session) throws Exception {
((Logger) LOG).info("心跳超时!");
}
}
以上的方法只能在第一次连上,当网络中断后,或者服务器突然断电重启后,就不会自动连接了,因此需要在通道关闭的地方做重连处理:
@Override
public void sessionClosed(IoSession session) throws Exception {
Log.d("session","连接断开");
i=0;
while(true) {
try {
Thread.sleep(3000);
// 这里是异步操作 连接后立即返回
ConnectFuture future = connector.connect(new InetSocketAddress(
IP, PORT));
future.awaitUninterruptibly();// 等待连接创建完成
session = future.getSession();
if(session.isConnected()) {
break;
}else{
Toast.makeText(getBaseContext(), "请检查网络", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
}
}
}