2

我正在使用 Netty 3.6.6.Final 并尝试为我的处理程序实现写入超时,以便在超时时我需要编写特定的响应。此外,我需要取消当前正在管道中执行(或将要执行)的另一个写入响应。

这是我目前的管道:

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

处理程序扩展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();                
        }});
} 

messageReceived问题是如果没有发生超时,我如何取消我在方法中计划的写入。Netty 中是否有处理此类问题的习惯?

编辑

通过取消ChannelFuture无效。据我了解,大部分时间写不会被取消。在我的测试中,它一直都是,即cancel()总是返回错误。所以我想以这种方式实现它真的很难。

最后,我将代码更新到了最新版本 - 4.0.9.Final(更好的 API)。突然之间,由于写入超时,我收到了响应。这在 3.6.6.Final 中没有这种方式。

在 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);

             }
         }
}

不知道在发生超时时“覆盖”第一次写入尝试是否是正确的方法,如果有人能解释它为什么起作用以及最新版本中关于这种情况的变化,我会很高兴。

4

2 回答 2

1

当消息被刷新时,promise 被设置为不可取消。一旦消息被写出一个字节,它必须被完全写入,以便解码器可以处理基于流的传输

于 2017-11-01T11:35:20.587 回答
0

您可以尝试 Channel 写入操作返回的 ChannelFuture。

于 2013-09-11T18:46:51.970 回答