2015-12-17 38 views
0

我目前使用的Netty 4.0,如果該事項,但不管怎麼說..了Netty - 跳過處理的其餘部分在管道

我有一個處理程序寫的讓我想篩選出取決於URI請求:

public class URIFilterHandler extends SimpleChannelInboundHandler<HttpRequest> { 

public void channelRead0(ChannelHandlerContext ctx, HttpRequest req) { 
    String uri = req.uri(); 

    if (uri.contains("abcde")) { 
     HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.NO_CONTENT); 
     ctx.writeAndFlush(response); 
     // HERE IS WHERE I WANT TO SKIP REST OF THE HANDLERS 

    } else { 
     ctx.fireChannelRead(req); 
    } 
} 
} 

然後這裏是我的管道

public class ServerInitializer extends ChannelInitializer<SocketChannel> { 

    @Override 
    public void initChannel(SocketChannel ch) { 
     ChannelPipeline p = ch.pipeline(); 

     p.addLast(new HttpRequestDecoder()); 
     p.addLast(new HttpResponseEncoder()); 
     p.addLast(new URIFilterHandler()); 
     p.addLast(new HttpObjectAggregator(1048576)); 
     p.addLast(new RequestHandler()); 

    } 
} 

我嘗試以下,但它似乎永久地從管線上拆下這些處理程序,而不是隻爲一個請求。

 ctx.pipeline().remove(HttpObjectAggregator.class); 
     ctx.pipeline().remove(RequestHandler.class;) 

我嘗試使用ctx.channel()。close()和ctx.fireChannelInactive()無濟於事。它似乎仍然將請求傳遞到下一個處理程序(在這種情況下爲HttpObjectAggregator)。我認爲這可能是由於close()和fireChannelInactive()是異步的?

編輯:看來我是有被我發回一個DefaultHttpResponse問題。當我發回一個DefaultFullHttpResponse時,請求不會掛起。

回答

0

如果您在channelRead0中沒有調用ctx.fireChannelRead(),則消息不會傳播到以下處理程序。這可以用下面的代碼段,其中第一個處理程序過濾掉所有的奇數證明:

EmbeddedChannel channel = new EmbeddedChannel(
      new SimpleChannelInboundHandler<Integer>() { 
       @Override 
       protected void channelRead0(ChannelHandlerContext ctx, 
         Integer msg) throws Exception { 
        if (msg % 2 == 0) 
         ctx.fireChannelRead(msg); 
       } 
      }, 
      new ChannelInboundHandlerAdapter() { 
       @Override 
       public void channelRead(ChannelHandlerContext ctx, 
         Object msg) throws Exception { 
        System.out.println(msg); 
       } 
      }); 

    channel.writeInbound(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 
+0

下一個處理程序是HttpObjectAggregator。我得到這個異常: io.netty.handler.codec.DecoderException:io.netty.handler.codec.MessageAggregationExceptionat io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:99) 這似乎表明它被傳遞到下一個處理程序,即使我不點火ctx.fireChannelRead() 我也應該補充的是,HTTP響應被正確返回,但我看到 – yeenow123

+0

似乎已經找到了一個日誌異常解決方案..而不是擴展SimpleChannelInboundHandler,擴展ChannelInboundHandlerAdapter並覆蓋channelRead(而不是channelRead0)。這是因爲channelRead的實現似乎默認調用fireChannelRead。 – yeenow123

+0

嗯,上面的方法似乎並沒有傳遞給其他處理的消息時,我想它,即使我打電話ctx.fireChannelRead()和請求只是掛起 – yeenow123

1

要跳過處理的其餘部分,只是什麼也不做。要繼續下一個處理程序來處理數據,與最初的對象或彼此,叫ctx.fireChannelRead(object)

保重引用計數的對象。 SimpleChannelInboundHandler默認釋放輸入(取決於構造函數參數)。如果您決定將其發送給下一個處理程序,則必須致電ReferenceCountUtil.retain(Object)。 查看文檔在這裏:http://netty.io/wiki/reference-counted-objects.html

而且,我覺得你應該把HttpObjectAggregator處理程序上流水線自己的處理程序之前,使您的處理程序捕獲FullHttpRequestHttpObjectAggregator爲你處理所有的http chunck,並穿上管道FullHttpRequest。在你的情況下,它可能是interessing,因爲如果你忽略一個chunck,你怎麼做與其他chunck已經聚集在管道上?我想你可能會有一個DecoderException拋出,如果你什麼都不做。

+1

的ReferenceCountUtil.retain(對象)是有用的,謝謝! – yeenow123