mina服务端检测客户端心跳实例

服务端代码

public class MyServer {
    /** 30秒后超时 */
    private static final int IDELTIMEOUT = 30;
    /** 15秒发送一次心跳包 */
    private static final int HEARTBEATRATE = 15;
    /** 心跳包内容 */
    private static final String HEARTBEATREQUEST = "xixixi";//预设请求内容
    private static final String HEARTBEATRESPONSE = "hahaha";//预设应答内容(记得客户端在接收到预设请求内容回复给服务端一定也是这个内容哦)
    public static void main(String[] args) throws IOException {
        IoAcceptor acceptor = new NioSocketAcceptor();
        acceptor.getSessionConfig().setReadBufferSize(2048);
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
                IDELTIMEOUT);

        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
//        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
        //心跳检测开始
        KeepAliveMessageFactory heartBeatFactory = new KeepAliveMessageFactoryImpl();
        KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory,
                IdleStatus.BOTH_IDLE);

        //设置是否forward到下一个filter
        heartBeat.setForwardEvent(true);
        //设置心跳频率
        heartBeat.setRequestInterval(HEARTBEATRATE);
        //设置失败处理handler
        heartBeat.setRequestTimeoutHandler(new KeepAliveRequestTimeoutHandlerImpl());
        acceptor.getFilterChain().addLast("heartbeat", heartBeat);
        //心跳检测结束
        acceptor.setHandler(new MyIoHandler());
        acceptor.bind(new InetSocketAddress(9123));
        System.out.println("Server started on port:9123" );
    }
    private static class KeepAliveMessageFactoryImpl implements KeepAliveMessageFactory {
        @Override
        public boolean isRequest(IoSession ioSession, Object o) {
            System.out.print("服务端判断消息是否为请求包消息: "+o);
            if (o.equals(HEARTBEATREQUEST))
                return true;
            return false;
        }

        @Override
        public boolean isResponse(IoSession session, Object message) {
            System.out.print("服务端判断响应心跳包信息: " + message);
            if(message.equals(HEARTBEATRESPONSE))
                return true;
            return false;
        }

        @Override
        public Object getRequest(IoSession session) {
            System.out.print("服务端发送给客户端的心跳包消息: " + HEARTBEATREQUEST);
            return HEARTBEATREQUEST;
        }

        @Override
        public Object getResponse(IoSession session, Object request) {
            System.out.print("响应预设信息: " + HEARTBEATRESPONSE);
            return HEARTBEATRESPONSE;
//          return null;
        }

    }
    private static class  KeepAliveRequestTimeoutHandlerImpl implements KeepAliveRequestTimeoutHandler{
        @Override
        public void keepAliveRequestTimedOut(KeepAliveFilter keepAliveFilter, IoSession ioSession) throws Exception {
            ioSession.close(true);
            System.out.print("客户端挂了  我把session给干掉了!");
        }
    }
}


客户端代码(在这里只提供客户端handler部分)

/** 心跳包内容 */
private static final String HEARTBEATREQUEST = "xixixi";
private static final String HEARTBEATRESPONSE = "hahaha";

@Override
public void messageReceived(IoSession ioSession, Object o) throws Exception {
    String s = o.toString();
    
    if(o.equals(HEARTBEATREQUEST)){
        ioSession.write(HEARTBEATRESPONSE);
    }
}


      这里简述一下心跳检测的过程,mina在一定时间内发现客户端与服务端没有通信的情况下会调用KeepAliveFilter里面的sessionIdle方法来获取空闲时预设的发送给客户端的消息,然后发送给客户端,客户端接收到消息后恢复给服务端预设响应的消息,服务端收到消息并判断是否为预设定的响应消息,如果是的话就证明客户端活着,如果长时间收不到消息活着收到的消息不是预设定的响应消息后就会调用KeepAliveRequestTimeOutHandler接口里面的keepAliveRequestAliveTimedOut方法(在这个方法里就可以实现自己的业务需求,记得在这个方法里面要把session关掉,不然服务端一直发送检测心跳的消息)。


      以上均是自己的理解,如有理解不正确的地方请指正,互相进步,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值