0

我正在构建一个 netty 代理服务器来查询 Opentsdb,如下所示:https ://github.com/AllenDevelop/Netty-proxy

它工作得很好。但出于调试目的,我添加了一段代码来记录接收和发送的 http 请求,问题是当我这样做时,Opentsdb 不会给我发回响应。

我添加的代码和原始代码一起是这样的(我将添加的代码提取为名为 logMessage 的方法)(此代码也不起作用):

public class NettyProxyServerHandler extends ChannelInboundHandlerAdapter {

private String remoteHost = "192.168.235.138";
private int remotePort = 4399;

private Channel outBoundChannel;

public NettyProxyServerHandler() {
    super();
}
public NettyProxyServerHandler(String remoteHost, int remotePort) {
    super();
    this.remoteHost = remoteHost;
    this.remotePort = remotePort;
}

@Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
    if(outBoundChannel==null || !ctx.channel().isActive()) {
        /* 创建netty client,连接到远程地址 */
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(ctx.channel().eventLoop())
                 .channel(ctx.channel().getClass())
                 .handler(new ChannelInitializer<SocketChannel>(){
                    @Override
                    protected void initChannel(SocketChannel ch)
                            throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast("codec", new HttpClientCodec());
                        pipeline.addLast("aggregator", new HttpObjectAggregator(1048576));
                        pipeline.addLast(new NettyProxyClientHandler(ctx.channel()));
                    }});
        ChannelFuture future = bootstrap.connect(remoteHost,remotePort);
        outBoundChannel = future.channel();

        /* channel建立成功后,将请求发送给远程主机 */
        future.addListener(new ChannelFutureListener(){
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    //this is what I added
                    logMessage((FullHttpRequest) msg);
                    future.channel().writeAndFlush(msg);
                } else {
                    future.channel().close();
                }
            }

        });
    } else {
        //this is what I added
        logMessage((FullHttpRequest) msg);
        outBoundChannel.writeAndFlush(msg);
    }
}

//I added this method.
private void logMessage(FullHttpRequest msg){
    ByteBuf m = msg.content();
    StringBuilder sb = new StringBuilder();
    while (m.isReadable()) {
        sb.append((char) m.readByte());
    }
    String content = sb.toString();
    StringBuilder sblog = new StringBuilder();
    sblog.append("msg:\n").append(msg.getMethod() + " " + msg.getUri() + " " + msg.getProtocolVersion() + "\n");
    for (Map.Entry<String, String> entry : msg.headers().entries()) {
        sblog.append(entry.getKey() + ": " + entry.getValue() + "\n");
    }
    sblog.append("\n").append(content);
    System.out.println(sblog.toString());
}

任何想法为什么以及在netty中记录http请求和响应的正确方法是什么?

4

1 回答 1

0

发现出了什么问题。我在 logMessage 方法中使用了 readByte() 方法,它会改变消息的 ByteBuf 的 readerIndex,这意味着消息的实际内容减少了。如果我改用 ByteBuf.toString(Charset)(此方法不会更改 readerIndex),我会得到服务器响应,如下所示:

String content = null;
    if(msg.content().isReadable()) {
        content = msg.content().toString(Charset.forName("UTF-8"));
    }
于 2018-07-06T07:25:42.400 回答