情況: 我重新使用proxy from the Netty 4 examples來創建我自己的。 該示例與我的實現之間的關鍵區別在於,代理僅在處理第一個協議數據單元后才連接到其遠程對等端。Netty 4 proxy:如何在第一個PDU之後停止讀取直到下一個read()調用?
我的前端處理程序的相關部分:
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.channel().read();// read the first message to trigger "channelRead0(...)"
}
@Override
protected void channelRead0(final ChannelHandlerContext ctx, UCPPacket ucpPacket) throws Exception {
if(!this.authenticated) {// authenticate the client then forward this packet
this.authenticateAndForwardPacket(ctx, ucpPacket);
} else {// forward the packet
this.forwardPacket(ctx, ucpPacket);
}
}
private void forwardPacket(final ChannelHandlerContext ctx, UCPPacket ucpPacket) {
if (outboundChannel.isActive()) {
outboundChannel.writeAndFlush(ucpPacket).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {// forwarding the packet succeeded so read the next one
ctx.channel().read();
} else {
future.channel().close();
}
}
});
} else { // this (often) happens when you don't set setSingleDecode(true) on the DelimiterBasedFrameDecoder
LOGGER.error("FIXME: avoid else");//FIXME: ...
}
}
管道: DelimiterBasedFrameDecoder
==>UcpDecoder
==>FrontendHandler
問題: 在Channel
第一read()
通常會讀取多個協議數據單元的字節,這意味着即使將AUTO_READ設置爲false,2個或更多個UCPPacket
也常常必須是 處理。我可以告訴Netty在解碼第一個UCPPacket
之後我完成了ByteBuf
(直到我再次呼叫read()
)?或者我還能做什麼?阻止前端處理程序的channelRead0
方法中的後續UCPPackets
,直到this.authenticated == true
顯然是不行(因爲這會阻塞IO線程)。
我的嘗試: 我試圖setSingleDecode(true)
上DelimiterBasedFrameDecoder
,但沒有很好地工作。第一幀得到正確解碼,但即使在代理已轉發該PDU並再次調用read()之後,DelimiterBasedFrameDecoder
也不會執行任何操作。我只能假設這是因爲read()調用判斷在沒有新讀入的入站字節時調用管道上的處理程序是「毫無意義的」。事情是...... Netty已經讀取了第二個(也是最後一個)UCPPacket
的字節,所以它將這些字節存儲在某個地方。注意:當我殺死客戶端進程時,代理會處理這些字節,這證明了我所說的:它確實有未處理的字節,它不會觸發處理程序。我猜想有一個decodeLast
或當通道不活動時被調用。
完成:https://github.com/netty/netty/issues/2072 – AndrewBourgeois
在我的情況DelimiterBasedFrameDecoder已經提供了這個功能,所以我需要的唯一的事情就是「pipeline.fireChannelRead(Unpooled.EMPTY_BUFFER) ;」而不是「ctx.channel()。read();」呼叫。 – AndrewBourgeois