如何在 HttpDecompressor 之前添加 GlobalTrafficShapingHandler

How to add the GlobalTrafficShapingHandler before HttpDecompressor

我想计算HttpDecompressor之前的压缩大小

我尝试调用 connection.addHandlerFirst,但没有用。

HttpClient.create()
    .mapConnect((connection, bootstrap) -> connection.map(
        conn -> {
            conn.addHandlerFirst(new ChannelInboundHandlerAdapter() {
                @Override
                public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                    if (msg instanceof HttpContent) {
                        System.out.println("received:" + msg);
                    }
                    super.channelRead(ctx, msg);
                }
            });
            return conn;
        }
    ))
    .compress(true);

使用 Connection#addHandlerFirst 无济于事,因为处理程序将在反应器编解码器之后添加。 More information here

您可以像这样将此处理程序直接添加到 Netty 管道中:

HttpClient.create()
        .mapConnect((connection, bootstrap) -> connection.map(
                conn -> {
                    conn.channel().pipeline().addBefore(NettyPipeline.HttpDecompressor, "myhandler",new ChannelInboundHandlerAdapter() {
                        @Override
                        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                            if (msg instanceof HttpContent) {
                                System.out.println("received:" + msg);
                            }
                            super.channelRead(ctx, msg);
                        }
                    });
                    return conn;
                }
        ))
    .compress(true);

但是你应该记住,一旦你将它直接添加到管道中,如果你使用连接池,这个处理程序也会为下一个请求保留(Connection#addHandlerFirst 不是这种情况)。因此,如果您仅针对特定请求需要它,那么您应该在收到响应后将其删除。 像这样:

HttpClient.create()
        .doOnResponse((res, conn) ->
                    conn.channel().pipeline().addBefore(NettyPipeline.HttpDecompressor, "myhandler",new ChannelInboundHandlerAdapter() {
                        @Override
                        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                            if (msg instanceof HttpContent) {
                                System.out.println("received:" + msg);
                            }
                            super.channelRead(ctx, msg);
                        }
                    }))
        .doAfterResponse((res, conn) ->
                    conn.channel().pipeline().remove("myhandler"))
        .compress(true)