我的i/o流程如下:
客户端将数据#1发送到通道
服务器(handler)根据客户机数据从数据库接收数据并发送给客户机
客户端将数据#2发送到通道
服务器(handler)根据客户机数据再次从数据库接收数据,并将其发送回客户机并关闭通道
若第一个读入通道花费的时间太长,readtimeouthandler将按预期触发异常。但如果第一次读取是正常的(=足够快),并且第二次在通道中读取花费的时间太长,则不会抛出timeoutexception,处理程序将等待5分钟,直到关闭通道。似乎readtimeouthandler只对第一个read-in通道有效。甚至可以让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));
}
...
}
}
公共类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条答案
按热度按时间cyej8jka1#
readtimeouthandler的行为是-如果在指定的持续时间内没有读取发生在通道中,它将引发异常并关闭通道。这不是因为响应或处理读取的延迟。在通道开始时,read标志设置为true,在读取完成时设置为false。调度程序运行时检查通道是否打开并且在指定的持续时间内没有读取,然后触发异常并关闭连接。
若第一个读入通道花费的时间太长,readtimeouthandler将按预期触发异常。
我觉得上面的说法不对。如果希望基于写入响应的延迟超时,可以考虑使用writetimeouthandler。