1

私は Netty 3.6.2 を使用しています。パイプライン ファクトリの疑似コードは次のとおりです。</p>

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() で何らかの例外が発生した場合に備えてチャネルを閉じたいと考えていますが、ここによると: http://netty.io/ wiki/thread-model.html

ダウンストリーム イベントの副作用としてトリガーされるアップストリーム イベントは、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);
}
}

しかし、うまくいかないようです。アドバイスをいただければ幸いです。

4

1 に答える 1

1

Channel#close() は、最終的に ChannelSink に到達するダウンストリーム イベントをトリガーします。ここで、イベントは、さらなる処理のためにチャネルに関連付けられたワーカーに「引き渡され」ます。ワーカーは最終的にチャネル クローズ イベントを発生させ、ワーカーはイベントが IO スレッドでアップストリームに送信されるようにします。

これが現在の動作方法です。参照しているドキュメントは、イベントが実際に呼び出しスレッドで配信された以前の状況について説明している可能性があります。

于 2013-05-05T11:34:10.140 に答える