考虑以下服务器引导代码:
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)是否应该是一个单独的处理程序(我们称之为“MyPingHandler”),它在 MyHandshakeHandler 或 B)之前添加到管道中,我应该将该逻辑添加到 MyHandshakeHandler 吗?
如果 A)我如何阻止消息进一步传播,以便不需要调用 MyHandshakeHandler,除非它专门是通道关闭事件(即 channelInactive())?作为奖励点 - 如果 MyPingHandler 仅在握手完成后添加到管道中会很好,这样它就不会被不必要地调用。
如果 B) 在这种情况下,我不明白 EventExecutorGroup 的目的。这些连接是该服务器将支持的唯一类型....所以设置一组专用的线程组似乎很奇怪,这些线程组将用于每个单独的处理程序,而不仅仅是使用默认值。因此,如果 B 是解决这个特定情况的方法——我是否应该在没有 EventExecutorGroup 的情况下正常地将处理程序添加到管道中(如果不是——为什么不呢)?