2016-08-04 3 views
0

タイトルによると、受信したメッセージはio.netty.channel.socket.DatagramPacketインスタンスであり、 メッセージの参照カウントは0です。私はそれを保持することはできませんし、それも解放することはできません。私はなぜこの問題に対処できないのでしょうか? 次のように私のハンドラは、ChannelInboundHandlerAdapterを拡張します。Netty UDP、受信時にメッセージの参照カウントがすでに0になっています

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になった私は(保持している場合)または解除( )、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

あなたは以前、あなたのパイプラインのMessageToMessageDecoderを持っている、とドキュメントの状態として、あなたが実際にそれをデコードすることなく、メッセージを通過する場合decode()方法でretain()を呼び出す(あるいはバッファの一部を再利用する)必要があります。

+0

私の質問に答えるいただきありがとうございます、私は自分のcode.IでMessageToMessageDecoderを持っていますあなたのメソッドを試してみます。もう一度おねがいします。 –

+0

これはあなたの質問には直接関係しませんが、DatagramPacketを「外部」のアクタに送信するのは危険です。バッファのライフサイクルを管理するためにかなりのメンテナンスの問題があります。 –

関連する問題