简体   繁体   English

如何取消Netty中的超时写?

[英]How to cancel write on timeout in Netty?

I am using Netty 3.6.6.Final and trying to implement write timeout for my handler such that on timeout I need to write specific response. 我正在使用Netty 3.6.6.Final并尝试为我的处理程序实现写入超时,以便在超时时我需要写入特定的响应。 In addition I need to cancel another write response which is currently executing in the pipeline (or will be executing). 另外,我需要取消另一个正在管道中执行(或将要执行)的写响应。

Here is my current pipeline: 这是我当前的管道:

bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
      public ChannelPipeline getPipeline() throws Exception {
         return Channels.pipeline(LOGGER,
            new HttpServerCodec(), 
            new MyHttpContentDecoder(), 
            new IdleStateHandler(timer, 0, 1000, 0, TimeUnit.MILLISECONDS),
            handler.get());
         }
});

Handler extends IdleStateAwareChannelHandler and implementing channelIdle method where I check for write timeout: 处理程序扩展了IdleStateAwareChannelHandler并实现了我检查写入超时的channelIdle方法:

if (e.getState() == IdleState.WRITER_IDLE) {
             e.getChannel().write(SOME_RESPONSE).addListener(new ChannelFutureListener() {          
         public void operationComplete(ChannelFuture future)  throws Exception {
            future.getChannel().close();                
        }});
} 

The question is how do I cancel write which I have planned in messageReceived method in case no timeout occurs. 问题是在没有超时的情况下如何取消在messageReceived方法中计划的写入。 Is there something customary in Netty to deal with such a problem? Netty是否有一些常规方法可以解决此类问题?

EDIT 编辑

Cancelling via ChannelFuture does not work. 通过ChannelFuture取消不起作用。 As far as I understand most of the time write will not be cancelled. 据我了解,大部分时间写操作不会被取消。 During my tests it was all the time, ie cancel() always returned false. 在我的测试过程中一直如此,即cancel()始终返回false。 So I guess it is really hard to achieve it this way. 因此,我想以这种方式实现它真的很困难。

In the end I have updated the code to the latest release - 4.0.9.Final (much nicer API). 最后,我将代码更新为最新版本-4.0.9.Final(更好的API)。 And all of the sudden, I received responses as a result of the write timeout. 突然之间,由于写入超时,我收到了响应。 That didn't work this way in 3.6.6.Final. 在3.6.6.Final中,这种方式不起作用。

In 4.0.9.Final the code for handling write timeout is a bit different but I always get a second write on timeout (if I comment ctx.writeAndFlush below, then I am getting write from channelRead0 ): 在4.0.9.Final处理写入超时的代码是有点不同,但我总是在超时第二写入(如果我评论ctx.writeAndFlush跌破的话,我正在写从channelRead0 ):

public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
         if (evt instanceof IdleStateEvent) {
             IdleStateEvent e = (IdleStateEvent) evt;
             if (e.state() == IdleState.WRITER_IDLE) {

                   //the following condition was always false 
                   //(channelFuture is a state  variable of my handler for previous write)
                   if (channelFuture != null && channelFuture.isCancellable()) {
                       System.out.println("Cancel "+channelFuture.cancel(true));
                   }

                  ctx.writeAndFlush(SOME_RESPONSE);

             }
         }
}

Don't know if it is the right way to "overwrite" first write attempt when timeout occurs, and would be glad if someone can explain why it works and what was changed in the latest release regarding this scenario. 不知道是否发生超时时“覆盖”首次写入尝试的正确方法,如果有人可以解释它的工作原理以及有关此情况的最新版本中发生了什么更改,将不胜感激。

您可以尝试引导由写操作返回的ChannelFuture。

when message is flushed, the promise is set to be uncancellable. 当刷新消息时,promise设置为不可取消。 Once a message is write out one byte, it must be write completely so that decoder can deal with a Stream-based Transport 一旦将消息写出一个字节,就必须将其完全写入,以便解码器可以处理基于流的传输

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM