我正在使用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()
总是返回 false。所以我想这样真的很难实现。
最后,我将代码更新到最新版本 - 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);
}
}
}
不知道在发生超时时"覆盖"第一次写入尝试是否是正确的方法,如果有人可以解释它为什么有效以及最新版本中有关这种情况的更改,将很高兴。
当消息被刷新时,承诺设置为不可撤销。一旦消息写出一个字节,它必须完全写入,以便解码器可以处理基于流的传输
您可以尝试引导写入操作返回的 ChannelFuture。