心跳:
1、自定义数据包,在业务逻辑里接收,客户端判断读写空闲,大于一个半的心跳之后,在空闲处理里将session关闭,注册的监听里断线重连
2、tcp的keepalive,服务端、客户端相互发确认心跳,设置好对应的心跳场景(服务端写空闲大于n秒后,每隔一个时间周期发送一个心跳1111,客户端读空闲大于n秒后,每隔一个时间周期发送一个心跳2222) 客户端设置超时时间,大于超时时间后,没有收到服务端心跳,认为连接不可用,主动关闭连接
代码实例:
package com.ydzq.hq.hk.mina.connect;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Server {
private static final int PORT = 9000;
/** 30秒后超时 */
private static final int IDELTIMEOUT = 30;
/** 15秒发送一次心跳包 */
private static final int HEARTBEATRATE = 15;
private static Logger log = LoggerFactory.getLogger(Server.class);
public static void main(String[] args) throws IOException {
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getSessionConfig().setReadBufferSize(1024);
acceptor.getSessionConfig().setIdleTime(IdleStatus.WRITER_IDLE,IDELTIMEOUT);
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec1", new ProtocolCodecFilter(new TextLineCodecFactory()));
KeepAliveMessageFactory heartBeatFactory = new KeepAliveMessageFactoryImpl();
//下面注释掉的是自定义Handler方式
KeepAliveRequestTimeoutHandler heartBeatHandler = new
KeepAliveRequestTimeoutHandlerImpl();
KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory,
IdleStatus.WRITER_IDLE, heartBeatHandler);
// KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory,
// IdleStatus.READER_IDLE);
//设置是否forward到下一个filter
heartBeat.setForwardEvent(true);
//设置心跳频率
heartBeat.setRequestInterval(HEARTBEATRATE);
acceptor.getFilterChain().addLast("heartbeat", heartBeat);
acceptor.setHandler(new MyIoHandler());
acceptor.bind(new InetSocketAddress(PORT));
log.info("Server started on port: " + PORT);
}
}
package com.ydzq.hq.hk.mina.connect;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Provides keep-alive messages to KeepAliveFilter.
*
*/
public class KeepAliveMessageFactoryImpl implements
KeepAliveMessageFactory {
private Logger log = LoggerFactory.getLogger(this.getClass());
/** 心跳包内容 */
private static final String SERVERHEARTBEATREQUEST = "1111";
private static final String SERVERHEARTBEATRESPONSE = "1112";
/*
*返回给客户端的心跳包数据 return 返回结果才是客户端收到的心跳包数据
*/
@Override
public Object getRequest(IoSession session) {
return SERVERHEARTBEATREQUEST;