Netty UDP,当我收到消息时,消息的引用计数已经为0

时间:2016-08-04 09:12:47

标签: netty

正如标题所说,收到的消息是io.netty.channel.socket.DatagramPacket实例和引用计数 收到邮件是0。我不能保留()它,也不能释放()它。我不知道为什么以及如何处理这个问题? 我的处理程序扩展了ChannelInboundHandlerAdapter,如下所示:

public class ActorMessageHandler extends ChannelInboundHandlerAdapter {
private Logger logger = LoggerFactory.getLogger(ActorMessageHandler.class);

private ActorRef messageHandlerActor;

public ActorMessageHandler(ActorRef handler) {
    this.messageHandlerActor = handler;
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    logger.info("actor message handler connected-{}", messageHandlerActor);
}

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    logger.info("disconnected...");
}

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    logger.debug("get message {}", msg);
    if (msg instanceof TransportMsg) {
        messageHandlerActor.tell(msg, ActorRef.noSender());
        return;
    }
    if (msg instanceof DatagramPacket) {
        //DatagramPacket recv = ((DatagramPacket) msg).retain();
        DatagramPacket recv = (DatagramPacket) msg;
        logger.info("recv refCnt: {}, {}", recv.content().refCnt(), recv.refCnt());
        DatagramPacket rsp = new DatagramPacket(recv.content().retain(), recv.sender(), recv.recipient());
        messageHandlerActor.tell(msg, ActorRef.noSender());
        if (rsp.refCnt() <= 0) {
            rsp.retain();
        }
        ctx.writeAndFlush(rsp);
        return;
    }
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    logger.error("Connection error: " + cause.getMessage());
    cause.printStackTrace();
}

}

我在收到DatagramPacket时记录了refCnt,并且在方法channelRead()中输出了0。如果我keep()或release(),则会触发IllegalReferenceCountException。

io.netty.util.IllegalReferenceCountException: refCnt: 0, increment: 1
at io.netty.buffer.AbstractReferenceCountedByteBuf.retain(AbstractReferenceCountedByteBuf.java:63)
at io.netty.buffer.WrappedByteBuf.retain(WrappedByteBuf.java:799)
at com.boer.handler.ActorMessageHandler.channelRead(ActorMessageHandler.java:44)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)
at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:92)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:745)

1 个答案:

答案 0 :(得分:1)

您的管道中有一个MessageToMessageDecoder,并且正如文档所述,如果您在没有实际解码的情况下传递消息,则必须在retain()方法中调用decode()(或重用缓冲区的某些部分。)