2013-12-16 66 views
1

情況: 我重新使用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或當通道不活動時被調用。

回答

1

因爲我們不知道應該讀取多少數據,所以您需要將它們排列在某處並自行處理。我想我們可以提供一個通用的ChannelInboundHandler來排隊消息。

你還介意打開一個問題,我們可以提供這樣一個處理程序嗎?

https://github.com/netty/netty/issues

+0

完成:https://github.com/netty/netty/issues/2072 – AndrewBourgeois

+0

在我的情況DelimiterBasedFrameDecoder已經提供了這個功能,所以我需要的唯一的事情就是「pipeline.fireChannelRead(Unpooled.EMPTY_BUFFER) ;」而不是「ctx.channel()。read();」呼叫。 – AndrewBourgeois

相關問題