2

考虑以下服务器引导代码:

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 的情况下正常地将处理程序添加到管道中(如果不是——为什么不呢)?

4

1 回答 1

3

答案是(A)。

要将事件传播到其下一个处理程序,您通常调用一个ctx.fireXXX()方法。如果您不调用其中任何一个,则不会传播该事件。因此,在您的情况下,您可以在握手完成后通过调用ctx.fireXXX()方法在大多数情况下吞下事件。

此外,管道可以动态配置。您可以随时在管道中添加或删除处理程序。因此,您可以在握手结束后删除握手处理程序,也可以在握手结束后添加 ping 处理程序(或两者兼而有之)。

于 2012-11-05T07:48:24.387 回答