MINA无法回调messageReceived函数


本文是在Android客户端上与服务器建立长连接,固定时间端发送心跳包。但发送初始化消息后,一直不能回调IoHandlerAdapter的messageReceived函数,虽然已经打印了接收Log(RECEIVED: HeapBuffer[...])。

本文基于:mina-core-2.0.16.jar和slf4j-android-1.6.1-RC1.jar,主要代码如下:

......
connector = new NioSocketConnector();
connector.setConnectTimeoutMillis(PushConstant.CONNECT_TIMEOUT);

// 设置日志输出工厂
connector.getFilterChain().addLast("logger", new LoggingFilter());
// 设置请求和响应对象的编解码操作
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ByteArrayCodecFactory()));
// 创建心跳工厂
ClientKeepAliveMessageFactory heartBeatFactory = new ClientKeepAliveMessageFactory();
// 当读操作空闲时发送心跳
KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory, IdleStatus.READER_IDLE);
// 设置是否将事件继续往下传递
heartBeat.setForwardEvent(true);
// 设置心跳包请求后超时无反馈情况下的处理机制,默认为关闭连接,在此处设置为输出日志提醒
heartBeat.setRequestTimeoutHandler(KeepAliveRequestTimeoutHandler.LOG);
//设置心跳频率
heartBeat.setRequestInterval(180);
connector.getFilterChain().addLast("keepAlive", heartBeat);

// 设置接收和发送缓冲区大小
connector.getSessionConfig().setReceiveBufferSize(1024);
connector.getSessionConfig().setSendBufferSize(1024);
// 设置读取空闲时间:单位为s
connector.getSessionConfig().setReaderIdleTime(180);

// 设置长连接业务逻辑处理类Handler
LongConnectHandler longConnectHandler = new LongConnectHandler();
connector.setHandler(longConnectHandler);

......
......

private class LongConnectHandler extends IoHandlerAdapter {
 
        @Override
        public void sessionCreated(IoSession session) throws Exception {
            super.sessionCreated(session);
        }


        @Override
        public void sessionClosed(IoSession session) throws Exception {
            super.sessionClosed(session);
        }

        @Override
        public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
            super.exceptionCaught(session, cause);
        }

        @Override
        public void messageReceived(IoSession session, Object message) throws Exception {
            System.err.println("接受消息成功...");
            super.messageReceived(session, message);
        }

        @Override
        public void messageSent(IoSession session, Object message) throws Exception {
            super.messageSent(session, message);
        }
}


ClientKeepAliveMessageFactory类实现如下:

private class ClientKeepAliveMessageFactory implements KeepAliveMessageFactory {


        @Override
        public boolean isRequest(IoSession ioSession, Object o) {
            return false;
        }

        @Override
        public boolean isResponse(IoSession ioSession, Object o) {
            return false;
        }

        @Override
        public Object getRequest(IoSession ioSession) {
            try {
                return IoBuffer.wrap(heartBeat().bytes());
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        public Object getResponse(IoSession ioSession, Object o) {
            return null;
        }
    }


搜到网上说是编解码错误,导致没有回调,但单步调试并没有发现错误。后来将ClientKeepAliveMessageFactory的isResponse的返回值从true改成了false,回调居然正常了,查看KeepAliveFilter.java源码:

    @Override
    public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
        try {
            if (messageFactory.isRequest(session, message)) {
                Object pongMessage = messageFactory.getResponse(session, message);

                if (pongMessage != null) {
                    nextFilter.filterWrite(session, new DefaultWriteRequest(pongMessage));
                }
            }

            if (messageFactory.isResponse(session, message)) {
                resetStatus(session);
            }
        } finally {
            if (!isKeepAliveMessage(session, message)) {
                nextFilter.messageReceived(session, message);
            }
        }
    }
	
	
    private boolean isKeepAliveMessage(IoSession session, Object message) {
        return messageFactory.isRequest(session, message) || messageFactory.isResponse(session, message);
    }

从源码可知,只有不是KeepAlive消息时,才将回调下一个Filter的messageReceived函数。





参考文献:

1、http://bbs.csdn.net/topics/390173203

2、https://my.oschina.net/yjwxh/blog/174633

3、http://blog.csdn.net/kkk0526/article/details/51732437

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值