正如标题所说,收到的消息是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)
答案 0 :(得分:1)
您的管道中有一个MessageToMessageDecoder
,并且正如文档所述,如果您在没有实际解码的情况下传递消息,则必须在retain()
方法中调用decode()
(或重用缓冲区的某些部分。)