I'm new to Netty, but I've worked with NIO a bit recently.
I'm building a UDP server, and it seems from the examples I've tried that unlike the NioServerSocketChannel.class
, when you use the NioDatagramChannel.class
you cannot assign an EventLoopGroup
workerGroup
to handle the Datagrams once they've been accepted by the socket. My code, based on the Netty QuoteOfTheMoment server example looks like this:
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();
}
}
This works perfectly fine, right now the PositionServerHandler
simply outputs the messages to the console.
I want to push the messages into a database, they're JSON strings, so I'd like to convert them to JSON first. I don't want to do the in the bossGroup
as it'll block with the database accessing and JSON processing. But I can't see an obvious way to add a workerGroup
.
Googling didn't reveal much either, except that my workerGroup
in this case should probably be an EventExecutorGroup
and not an EventLoopGroup
, but I'm not even 100% certain about that.
In NIO, I would have two thread pools, and I'd use some sort of queue, one pool of threads would push Strings to the queue, the other would take Strings from the queue, convert them to JSON objects and push them to the database.
Can I do something similar in Netty?
In which case my PositionServerHandler.class
would accept a queue in the constructor, and push either whole DatagramPackets
to it, or the message contents, then have another EventLoopGroup
/EventExecutorGroup
to take those messages and push them to the database.
It seems that ServerBootstrap
doesn't handle NioDatagramChannels
for some reason, that doesn't make sense to me.
Is this feasible? Am I missing some obvious solution to this?
Can I do something similar in Netty?
Yes. But first a clarification of terminology. In typical TCP server samples, the "boss group" is the event loop group that does TCP accept. The "worker group" is the event loop group that does TCP receive. Since UDP sockets do not "accept", but they do receive, the distinction between boss group and worker group is meaningless, and in the cited example, the variable is just called "group". It performs the same function as "worker group" in a typical TCP server, namely, it processes the incoming data.
Keep in mind that a single NioEventLoopGroup contains a thread pool which can be configured to have any number of threads.
In NIO, I would have two thread pools, and I'd use some sort of queue...
You can use the same design. You are still using NIO after all - you just have Netty to help you. The NioEventLoop "worker" group is your "first" thread pool which pushes Strings to the queue. Create your second thread pool any way you want, either using the standard Java APIs or using a second netty event loop group which is not attached to any channel. Everything else remains the same.