Netty:如何确保I / O线程触发了Channel.close()

时间:2013-05-04 06:52:03

标签: netty

我使用的是Netty 3.6.2,这是我的管道工厂伪代码:

private final static ThreadPoolExecutor executor = new OrderedMemoryAwareThreadPoolExecutor(8, 4194304, 4194304, 5L, TimeUnit.MINUTES);
public ChannelPipeline getPipeline() throws Exception {
    ChannelPipeline p = pipeline();
    p.addLast("frameDecoder", protobufFrameDecoder);
    p.addLast("protobufDecoder", protobufDecoder);
    p.addLast("executor", new ExecutionHandler(executor));
    p.addLast("handler", handler);
    p.addLast("frameEncoder", protobufFrameEncoder);
    p.addLast("protobufEncoder", protobufEncoder);
    return p;
}

以这种方式,处理程序的messageReceived()在不同的线程池而不是工作线程池中被调用,现在我想在messageReceived()中发生一些异常时关闭通道,但是根据这里:{ {3}},

  

作为下游事件的副作用而触发的任何上游事件   必须从I / O线程中触发。

简单地调用ctx.getChannel()。close()在exceptionCaught()中是不安全的,我试图用这种方式来解决这个问题,

NettyServerSocketFactory.getWorkerExecutor().execute(new Runnable() {
   @Override
   public void run() {
       channel.close();
   }
});

这里是NettyServerSocketFactory代码:

public class NettyServerSocketFactory extends NioServerSocketChannelFactory {

private static Executor bossExecutor = Executors.newCachedThreadPool();
private static Executor workerExecutor = Executors.newCachedThreadPool();

public static Executor getBossExecutor() {
    return bossExecutor;
}

public static Executor getWorkerExecutor() {
    return workerExecutor;
}

public NettyServerSocketFactory() {
    super(bossExecutor, workerExecutor);
}
}

但似乎行不通,任何建议都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

频道#close()触发一个下游事件,该事件将通过频道到达ChannelSink,事件被“移交”给与该频道相关联的工作人员以进行进一步处理。工作人员最终将触发一个通道关闭事件,工作人员将确保该事件在IO线程上游发送。

这就是它目前的工作方式,也许您所指的文档正在讨论之前的情况,其中事件确实是在调用线程上传递的。