mina自带了心跳包机制,我是每隔15秒发送一次心跳包,若30秒内没有收到,则认为超时。
网络连接的主题函数是:
/*** 30秒后超时*/private static final int IDELTIMEOUT = 30;/*** 15秒发送一次心跳包*/private static final int HEARTBEATRATE = 15;
new Thread(new Runnable() {@Overridepublic 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)*/@Overridepublic 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)*/@Overridepublic 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)*/@Overridepublic 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)*/@Overridepublic 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)*/@Overridepublic void keepAliveRequestTimedOut(KeepAliveFilter filter, IoSession session) throws Exception {((Logger) LOG).info("心跳超时!");}}
以上的方法只能在第一次连上,当网络中断后,或者服务器突然断电重启后,就不会自动连接了,因此需要在通道关闭的地方做重连处理:
@Overridepublic 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) {}}}