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