【问题标题】:choosing either simplehandler or executor in netty 4.0在 netty 4.0 中选择 simplehandler 或 executor
【发布时间】:2012-10-19 16:27:21
【问题描述】:

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

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

【问题讨论】:

    标签: java netty


    【解决方案1】:

    答案是(A)。

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

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

    【讨论】:

    • 谢谢 - 快速提问,我相信入站消息是通过覆盖 messageReceived() 接收的,而不是事件。那么不调用 ctx.fireXXX() 是否仍会阻止管道中的下一个处理程序?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 2013-08-09
    • 1970-01-01
    • 2015-11-15
    • 2012-12-21
    • 1970-01-01
    相关资源
    最近更新 更多