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

如果通道中有多次读取,Netty - fire ReadTimeoutHandler

长孙谦
2023-03-14

我的I/O流如下:

    < li >客户端向通道发送数据# 1 < li >服务器(处理程序)根据客户端数据从数据库接收数据,并将其发送给客户端 < li >客户端向通道发送数据# 2 < li >服务器(处理程序)根据客户端数据再次从数据库接收数据,并将其发送回客户端,然后关闭通道

如果首次在通道中读取花费的时间太长,则读取超时处理程序将按预期触发异常。但是,如果第一次读取没问题(= 足够快),并且通道中的第二次读取花费的时间太长,则不会引发超时异常,并且处理程序会等待 5 分钟,直到它关闭通道。似乎读取超时处理程序仅适用于通道中的第一个读取。甚至有可能让读取超时处理程序处理通道中的多个读取?

使用的Netty版本:4.0.12

公共类我的服务器 {

private static final class MyInitializer extends ChannelInitializer<SocketChannel> {

...

    @Override
    public void initChannel(SocketChannel channel) throws Exception {
        channel.pipeline().addLast(
                new ReadTimeoutHandler(5, TimeUnit.SECONDS),
                new MyHandler(server, serverConnection));
    }

...

}

}

公共类MyHandler扩展了SimpleChannelInboundHandler{

private static final Logger LOG = LoggerFactory.getLogger(MyHandler.class);

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    super.channelActive(ctx);
}

@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
    Message message = database.getMessage(msg);
    ChannelFuture operation = ctx.writeAndFlush(message) 

if (message.isEnd()) operation.addListener(new CloseConverstationListener(ctx));
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    if (cause instanceof ReadTimeoutException) {
        LOG.error("ReadTimeoutException");
    } 
}

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    super.channelInactive(ctx);
}

private class CloseConverstationListener implements GenericFutureListener<ChannelFuture> {
    private final ChannelHandlerContext ctx;

    private CloseConverstationListener(ChannelHandlerContext ctx) {
        this.ctx = ctx;
    }

    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
        future.channel().close().sync();
    }
}

}

共有1个答案

宰父冠玉
2023-03-14

读取超时处理程序行为是 - 如果在指定的持续时间内通道中未发生读取,它将触发异常并关闭通道。这不是由于响应或处理读取的延迟。在通道开始时读取读取标志设置为 true,当读取完成时,该标志设置为 false。运行调度程序,检查通道是否打开且在指定持续时间内未读取,然后触发异常并关闭连接。

如果首次在通道中读取花费的时间太长,则读取超时处理程序将按预期触发异常。

以上听起来对我不正确。如果您希望基于写入响应的延迟而超时,您可以考虑使用WriteTimeoutHandler。

 类似资料:
  • 我正在使用Netty框架并实现客户端和服务器。我建立了多达1000个连接。我想在多个地方配置超时值。其中一些我能理解。下面是我的netty实现的netty行为: 1。许多异步连接都是从具有超时的客户端开始的(使用ChannelOption.CONNECT\u timeout\u MILLIS配置) 2。那些能够连接的客户端连接使用channelActive发送HTTP请求,并使用channelRe

  • 文件上说 请注意,此处理程序的管道覆盖范围为“全部”,这意味着必须仅创建一个此类处理程序并在所有通道之间共享,因为计数器必须在所有通道之间共享。 我理解必须共享此处理程序。 假设我有两组通道。我可以为每个组使用不同的GlobalChannelTrafficShapingHandler实例吗?

  • 我正在使用netty开发一个代理服务器,我的代理ProxyBackendHandler类如下所示。在channelRead方法中,我需要获取msg数据,并将其作为TextWebSocketFrame写入客户端。为此,我使用了StringBuilder和while循环来迭代ByteBuf。有没有人能给我一个更好的方法来做这件事,因为上面的代码在高数据负载时有很高的性能开销。

  • 问题内容: 我有以下代码: 和此web.xml(缩短了程序包并更改了名称,但外观相同) 我想在过滤器之后调用Servlet。我希望可以做到这一点,但是我总是会遇到以下错误: 问题答案: 你可能开始使用 in 使用HttpServletRequest : 你的servlet尝试调用相同的请求,这是不允许的。你需要做的是使用制作请求正文的副本,因此你可以使用多种方法读取它。

  • 问题内容: 我是Golang的新手。现在,我正在尝试找出如何在Golang中建立任意一对一频道的方法,其设置如下: 说我有两个goroutines numgen1和numgen2同时执行并将数字写入通道num1resp。num2。我想在新进程addnum中添加从numgen1和numgen2发送的数字。我已经尝试过这样的事情: 但这似乎令人遗憾。有人可以给我一些想法吗? 非常感谢您的帮助。 问题答

  • 我想创建一个可以重用通道的连接池,但我想不通 执行此测试 我在第二个频道遇到了ClosedChannel异常。写入(请求)。。。。 存在重用通道的方法吗?还是保持通道打开? 提前感谢