我目前正在使用Netty 4.0,如果这很重要,但无论如何..
我有一个像这样编写的处理程序,我想根据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 :(得分:2)
要跳过剩下的处理程序,就什么都不做。要继续使用下一个处理程序,初始对象或彼此处理数据,请调用ctx.fireChannelRead( object )
照顾引用计数的对象。 SimpleChannelInboundHandler
默认释放输入(取决于构造函数参数)。如果您决定将其发送到下一个处理程序,则必须调用ReferenceCountUtil.retain(Object)
。
请参阅此处的文档:http://netty.io/wiki/reference-counted-objects.html
此外,我认为您应该将HttpObjectAggregator
处理程序放在管道上自己的处理程序之前,并使处理程序捕获FullHttpRequest
。
HttpObjectAggregator
为您处理所有http chuncks,并将管道FullHttpRequest
放入管道。在你的情况下,它可能是有意思的,因为如果你忽略了一个chunck,你如何处理已经聚合在管道上的其他chuncks?我想如果你什么也不做,你可能会抛出DecoderException。
答案 1 :(得分:0)
如果您未在ctx.fireChannelRead()
中呼叫channelRead0
,则该消息将不会传播到以下处理程序。这可以通过以下代码片段来演示,其中第一个处理程序过滤掉所有奇数:
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);