在netty 4.0中选择simplehandler或executor

时间:2012-10-30 10:35:37

标签: java netty

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

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 个答案:

答案 0 :(得分:3)

答案是(A)。

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

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