次のサーバー ブートストラップ コードを検討してください。
ChannelFuture f;
ServerBootstrap b = new ServerBootstrap();
try {
b.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.localAddress(1234)
.childOption(ChannelOption.TCP_NODELAY, true)
.childHandler(new MyChannelInitializer(new DefaultEventExecutorGroup(10)));
f = b.bind().sync();
f.channel().closeFuture().sync();
}
そしてMyChannelInitializer.java :
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
private EventExecutorGroup executorGroup;
public MyChannelInitializer(EventExecutorGroup _executorGroup) {
executorGroup = _executorGroup;
}
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.nulDelimiter()));
pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
// and then business logic.
pipeline.addLast(this.executorGroup, "handler", new MyHandshakeHandler());
}
}
現在、MyHandshakeHandler() はメッセージをリッスンしており、これらのメッセージはデータベースと対話する必要があります。
さらに先に進む前に、上記のコードはこれを行う正しい方法ですか? (つまり、このブロッキングタイプのハンドラーに EventExecutorGroup を使用した方法)
今のところそれが正しいと仮定して、ここに私の質問があります。MyHandshakeHandler() がデータベースと対話する必要があるのは事実ですが、これはクライアントとの最初のネゴシエーション中およびチャネルのクローズ時のみです。残りの時間、つまりハンドシェイクが完了してチャネルが閉じられる前に必要なのは、データベースを必要としない ping/pong/heartbeat/keepalive タイプのメッセージをバウンスすることだけです。したがって、A) MyHandshakeHandler の前にパイプラインに追加される別のハンドラー (「MyPingHandler」と呼びましょう) にする必要がありますか、または B) そのロジックを MyHandshakeHandler に追加するだけですか?
A) 特にチャネルを閉じるイベント (つまり、channelInactive()) でない限り、MyHandshakeHandler が不必要に呼び出されないように、メッセージの伝播を停止するにはどうすればよいですか? おまけとして、MyPingHandler が不要に呼び出されないように、ハンドシェイクが完了した後にのみパイプラインに追加されると便利です。
B) この場合の EventExecutorGroup の目的がわかりません。これらの接続は、このサーバーが機能する唯一のタイプです....したがって、デフォルトを使用するのではなく、すべての単一ハンドラーに使用されるスレッドの専用グループを設定するのは奇妙に思えます。したがって、B が進むべき道である場合 (この特定のケースの場合)、EventExecutorGroup を使用せずに通常どおりハンドラーをパイプラインに追加する必要があります (そうでない場合)。