我正在构建一个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请求和响应的正确方法是什么?
答案 0 :(得分:0)
发现出了什么问题。我在logMessage方法中使用了readByte()方法,该方法将更改消息的ByteBuf的readerIndex,这意味着减少了消息的实际内容。如果我改用ByteBuf.toString(Charset)(此方法不会更改readerIndex),则会得到服务器响应,如下所示:
String content = null;
if(msg.content().isReadable()) {
content = msg.content().toString(Charset.forName("UTF-8"));
}