Netty - 如果在通道

时间:2016-05-10 07:00:00

标签: java netty

我的I / O流程如下:

  1. 客户端将数据#1发送到频道
  2. server(handler)根据客户端数据从数据库接收数据并将其发送到客户端
  3. 客户端将数据#2发送到频道
  4. server(handler)根据客户端数据从数据库再次接收数据并将其发送回客户端并关闭通道
  5. 如果第一次读入通道需要太长时间,ReadTimeoutHandler会按预期触发异常。但是如果第一次读取正常(=足够快)并且第二次读取通道需要太长时间,则不会抛出TimeoutException,并且处理程序等待5分钟直到它关闭通道。似乎ReadTimeoutHandler仅适用于通道中的第一次读取。甚至可以让ReadTimeoutHandler在通道中进行多次读取吗?

    使用过的Netty版本:4.0.12

    公共类MyServer {

    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));
        }
    
    ...
    
    }
    

    }

    public class 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 个答案:

答案 0 :(得分:0)

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

  

如果第一次读入通道需要太长时间,ReadTimeoutHandler会按预期触发异常。

以上对我来说听起来不对。 如果你想根据写入响应的延迟来超时,你可以考虑WriteTimeoutHandler。