我对netty比较陌生,如果我正确地做事,我不确定。我会尽量缩短。如果有任何疑问,请询问更多信息。在netty中处理HTTP客户端异常
所以,我有一个netty服务器提供HTTP请求,其中内容预计是序列化为Json字符串的protobuf消息。
通道管道是这样的:
@Override protected void initChannel(final SocketChannel channel) throws Exception {
final ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(1048576));
pipeline.addLast(new HttpProtobufServerCodec(charset, requestConverter, responseConverter));
pipeline.addLast(new ProtobufMessageHandler(mapping));
}
前两个通道处理程序是标准的网状的东西,
HttpProtobufServerCodec样子:
public class HttpProtobufServerCodec extends CombinedChannelDuplexHandler<HttpToProtobufDecoder, ProtobufToHttpEncoder>
和HttpToProtobufDecoder样子:
public final class HttpToProtobufDecoder extends MessageToMessageDecoder<FullHttpRequest> {
private Charset charset;
private final Converter<byte[], ?> converter;
protected HttpToProtobufDecoder(final Charset charset, final Converter<byte[], ?> converter) {
this.charset = charset;
this.converter = converter;
}
@Override protected void decode(final ChannelHandlerContext ctx, final FullHttpRequest msg, final List<Object> out)
throws Exception {
byte[] payloadBytes = new byte[msg.content().readableBytes()];
msg.content().readBytes(payloadBytes);
Message message = (Message) converter.convert(payloadBytes);
out.add(message);
}
@Override public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception {
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.BAD_REQUEST,
Unpooled.wrappedBuffer(charset.encode("Could not read request!").array()));
//ctx.writeAndFlush(response);
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
}
因此,我在HttpToProtobufDecoder中收到FullHttpRequest并尝试将请求的内容解码为protobuf消息。如果内容不能被解码,这将把我们置于exceptionCaught(...)方法中,这会引发异常。
在异常中捕获到HTTP 400响应并创建并写入channelHandlerContext。这是我的问题。
如果上下面的行评论被切换:
//ctx.writeAndFlush(response);
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
读取响应身体当客户端超时。但是如果我在写完400之后关闭频道,一切似乎都很好。会发生什么事;因为没有输入数据可用,所以输入流的读取被阻塞。即我们被困在下面in.read(...),远的地方倒在客户端代码:
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
byteCount += bytesRead;
}
所以,问题是,你有密切的渠道以书面出于某种原因HTTP 400响应后?
我是否会以正确的方式去做这件事?我应该在exceptionCaught中写入HTTP响应消息吗?
对不起,如果问题有点不清楚。任何帮助都感激不尽!
/谢谢!
谢谢!我自己得出了这个确切的结论。很高兴得到证实。我不知何故,虽然HttpServerCodec会/应该处理。 –