如何在Netty中使用带有NioDatagramChannel的EventExecutorGroup?

时间:2015-03-22 10:51:52

标签: java netty nio datagram

我是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 / {{1}获取这些消息并将它们推送到数据库。 似乎EventExecutorGroup由于某种原因无法处理ServerBootstrap,这对我来说没有意义。

这可行吗?我错过了一些明显的解决方案吗?

1 个答案:

答案 0 :(得分:2)

  

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

是。但首先澄清术语。在典型的TCP服务器示例中," boss组"是TCP接受的事件循环组。 "工人组"是TCP接收的事件循环组。由于UDP套接字不接受"但是它们确实接收,因此boss组和worker组之间的区别是没有意义的,并且在引用的示例中,变量只被称为" group"。它执行与"工作组"相同的功能。在典型的TCP服务器中,即它处理传入的数据。

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

  

在NIO中,我会有两个线程池,我会使用某种队列...

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