当前位置: 首页 > 知识库问答 >
问题:

处理netty中的HTTP客户端异常

董琦
2023-03-14

我对netty比较陌生,不确定自己做的事情是否正确。我会尽量短一点。如果有任何不清楚的地方,请询问更多信息。

因此,我有一个提供HTTP请求的netty服务器,其中的内容应该是序列化为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));
}

前两个通道处理程序是标准的netty工具,

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消息。如果无法解码内容,则抛出异常,这将使我们处于ExceptionCatch(...)方法..

在捕获异常时,创建HTTP 400响应并将其写入ChannelHandlerContext。这就是我的问题所在。

如果切换了以下行上的注释:

//ctx.writeAndFlush(response);
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);

客户端在读取响应正文时超时。但如果我在写完400之后关闭频道,一切似乎都很好。所发生的是;输入流的读取被阻止,因为没有可用的输入数据。即。我们被困在.read(...)下面,在客户端代码下面的某个地方:

while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
        byteCount += bytesRead;
    }

所以,问题是,您是否有关闭通道后,编写http 400响应由于某种原因?

我这样做对吗?我应该在ExceptionCatch中编写HTTP响应消息吗?

对不起,如果这个问题有点不清楚。任何帮助都将不胜感激!

/谢谢!

共有1个答案

魏晨
2023-03-14

客户端无法知道您的消息何时已完全发送。添加一个内容长度或分块头,您将不再需要关闭连接。

 类似资料:
  • 我有一个使用RESTEasy的简单客户端,如下所示: 服务器配置为在以及一条有用的信息。正在抛出一个。除了包装在中之外,我如何使捕获异常并以字符串形式返回响应的有用消息。我尝试了各种实现,但似乎都是正确的。上述代码从未调用。我错过了什么? 我目前的解决方法是使用,然后执行并将原始状态填充到响应实体中。这样我就避免了异常抛出。

  • 我试图理解netty http客户端连接池。如果是NIO和异步的,那么这个连接池的意义是什么? 例如:如果服务A调用服务B,并且服务A的客户端连接池计数设置为50,那么这是否意味着我们最多只能发出50个并行请求? 更新: 我在3.5秒内完成了所有通话。理想情况下,有一个连接,我应该在150秒内完成。

  • 我正在使用eclipse ide,当我运行我的程序时,一切正常,但当我在服务器上运行相同的程序时,它给我这个异常,我已经把我的所有far文件以及我的lib文件夹中,请帮助我简短地解决这个问题。 下面是我的代码:

  • 在构建Retor Netty应用程序时,我得到了两个相似的指标。但是它们之间到底有什么区别呢? vs. 我不知道他们在测量响应时间的方式/位置上有什么不同。哪种方法测量的时间更长并不一致。 Http客户端指标测量时间更长 ReactorNetty指标延长了时间

  • 那么如何提取错误代码呢?我想提取错误代码并构建一个responseEntity 我得到了这段代码,但不知道如何在函数中使用。

  • 我使用Apache Ignite 2.7.5作为.NET核心中服务器和瘦客户机。当我做与缓存相关的操作时,put、get和load等.net核心应用程序会自动崩溃。 因此,我想处理for循环内部的异常,例如、、等,然后从catch块抛出for循环,否则如果只有异常块,则继续循环迭代。