netty how to make server program not to quit

2019-08-27 03:03发布

I am trying to understand and use Netty in my projects, so started off with the basic DiscardServer Example presnted in Netty's user guide.

The below is almost a copy-paste of the original code...

public void run() throws Exception {
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap sb = new ServerBootstrap();
        sb.group(bossGroup, workerGroup);
        sb.channel(NioServerSocketChannel.class);
        sb.childHandler(new ChannelInitializer<SocketChannel>() {

            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new DiscardServerHandler());
            }
        });

        // Set some socket options such as socket queue backlog and keepalive.
        sb.option(ChannelOption.SO_BACKLOG, 128);
        sb.childOption(ChannelOption.SO_KEEPALIVE, true);

        // bind to port and start listening.
        ChannelFuture f = sb.bind(port).sync();

    } finally {
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }
}

And when I create a main method, as below, it runs fine, but then just gets terminated.

public static void main(String[] args) throws Exception {

    int port = Integer.parseInt(args[0]);
    System.out.println("Starting discard server...");
    new DiscardServer(port).run();
    System.out.println("Discard server returning...");
}

The program output is:

Starting discard server... Discard server returning...

And then the program terminates.

I am expecting that the event loop inside the netty classes should make my server, but it doesn't seem to happen that way. Should I write a while loop in my main method to ensure my server keeps running?

UPDATE:

The same program works flawlessly, if I use Netty 4.x series of jar files. I think the version 5 is still evolving, so errors are expected.

标签: netty
1条回答
倾城 Initia
2楼-- · 2019-08-27 03:14

You forgot to add the wait on close operation:

// Bind and start to accept incoming connections.
ChannelFuture f = b.bind(PORT).sync();
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();

What you do right now is starting the server to listen, then finishing your own main after shutdown your executors.

You have to block on something, and the best for the server is to wait on the closeFuture operation.

Then in your handler, you have to decide when to close the server (f.channel().close()), which will turn to awake the main procedure and finishing the server.

Important notice: you have to distinguish the "child" channel (which you get from ctx.channel() in your handler, attached to one unique client connection) and the "parent" channel (which you get from ctx.channel().parent()). Closing the "child" will not terminate the f.channel() since this one is the "parent" one (the listener). So you have to do something like ctx.channel().parent().close().

Note that the current example of DiscardServerHandler does not include any code to stop (it is a forever running handler).

查看更多
登录 后发表回答