在Netty 4.0中选择SimpleHandler还是Executor

3
考虑以下服务器引导代码:
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(如果不是-为什么不使用)?
1个回答

3
答案是(A)。
要将事件传播到其下一个处理程序,通常需要调用ctx.fireXXX()方法。如果您不调用它们中的任何一个,则该事件将不会被传播。因此,在您的情况下,可以在握手完成后大多数情况下吞咽事件,调用ctx.fireXXX()方法。
此外,管道可以动态配置。您可以随时向管道添加或删除处理程序。因此,您可以在握手完成后删除握手处理程序,或在握手完成后添加ping处理程序(或两者都添加)。

谢谢- 不过我有一个快速问题,我相信入站消息是通过覆盖messageReceived()方法接收的,而不是事件。那么如果不调用ctx.fireXXX(),是否仍会阻止管道中的下一个处理程序? - davidkomer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接