我正在使用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);
}
}
}
当超时发生时,不知道是否是“覆盖”第一次写入尝试的正确方法,并且如果有人可以解释为什么它有效以及最新版本中有关此方案的更改,将会很高兴。
答案 0 :(得分:0)
您可以尝试引导写操作返回的ChannelFuture。
答案 1 :(得分:0)
当刷新消息时,承诺被设置为不可取消。一旦消息写出一个字节,它必须完全写入,以便解码器可以处理基于流的传输