如何在 Netty 中将 EventExecutorGroup 与 NioDatagramChannel 一起使用?

How can I use an EventExecutorGroup with an NioDatagramChannel in Netty?

我是 Netty 的新手,但我最近使用过 NIO。 我正在构建一个 UDP 服务器,从我尝试过的示例看来,与 NioServerSocketChannel.class 不同,当您使用 NioDatagramChannel.class 时,您无法分配 EventLoopGroup workerGroup在数据报被套接字接受后处理数据报。我的代码基于 Netty QuoteOfTheMoment server 示例,如下所示:

public class PositionServer {

    int port;

    public PositionServer(int port) {
        this.port = port;
        System.out.println("Port set to " + this.port);
    }

    public void run() {
        EventLoopGroup bossGroup = new NioEventLoopGroup();

        try {

            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(bossGroup).channel(NioDatagramChannel.class)
            .handler(new PositionServerHandler());

            System.out.println("Binding to port " + port);
            bootstrap.bind(port).sync().channel().closeFuture().await();

        } catch (InterruptedException e) {
            bossGroup.shutdownGracefully();
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        new PositionServer(4000).run();

    }

}

这工作得很好,现在 PositionServerHandler 只是将消息输出到控制台。

我想将消息推送到数据库中,它们是 JSON 字符串,所以我想先将它们转换为 JSON。我不想在 bossGroup 中执行此操作,因为它会阻塞数据库访问和 JSON 处理。但是我看不到添加 workerGroup 的明显方法。

谷歌搜索也没有透露太多,除了我的 workerGroup 在这种情况下可能应该是 EventExecutorGroup 而不是 EventLoopGroup,但我什至不是 100%确定这一点。

在 NIO 中,我有两个线程池,我会使用某种队列,一个线程池将字符串推入队列,另一个线程池从队列中取出字符串,将它们转换为 JSON 对象并将它们推送到数据库。

我可以在 Netty 中做类似的事情吗?

在这种情况下,我的 PositionServerHandler.class 将在构造函数中接受一个队列,并将整个 DatagramPackets 或消息内容推送给它,然后有另一个 EventLoopGroup/EventExecutorGroup 获取这些消息并将它们推送到数据库。 似乎 ServerBootstrap 出于某种原因无法处理 NioDatagramChannels,这对我来说没有意义。

这可行吗?我是否缺少一些明显的解决方案?

Can I do something similar in Netty?

是的。但首先要澄清术语。在典型的 TCP 服务器示例中,"boss group" 是 TCP 接受的事件循环组。 "worker group" 是 TCP 接收的事件循环组。由于UDP sockets不"accept",但它们确实接收,bo​​ss组和worker组的区别是没有意义的,在引用的例子中,变量只是被称为"group"。它执行与典型 TCP 服务器中的 "worker group" 相同的功能,即处理传入数据。

请记住,单个 NioEventLoopGroup 包含一个线程池,可以将其配置为具有任意数量的线程。

In NIO, I would have two thread pools, and I'd use some sort of queue...

您可以使用相同的设计。毕竟你还在使用 NIO——你只是有 Netty 来帮助你。 NioEventLoop "worker" 组是您的 "first" 线程池,它将字符串推送到队列。使用标准 Java API 或使用未附加到任何通道的第二个 netty 事件循环组,以任何你想要的方式创建你的第二个线程池。其他一切都保持不变。