Netty关闭/停止UDP服务器

时间:2018-10-22 09:27:37

标签: java server udp netty shutdown

我正在尝试创建Netty UDP侦听器。我面临的问题是我无法像tcp一样停止udp服务器,即使使用shutdowngracely调用,udp始终在运行,停止它的唯一方法是抛出异常。

private int port;
private UDPViewModel viewModel;
private DefaultEventLoopGroup defaultEventLoopGroup;

public UdpServer(UDPViewModel viewModel, int port) {
   this.port = port;
   this.viewModel = viewModel;
}

@Override
public void run() {
    defaultEventLoopGroup = new DefaultEventLoopGroup();
    try {

        ServerBootstrap bootstrap = new ServerBootstrap()
                .channel(UdpServerChannel.class)
                .group(defaultEventLoopGroup)
                .childHandler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) {
                        channel.pipeline()
                                .addLast(new ReadTimeoutHandler(5))
                                .addLast(new UdpServerHandler(viewModel));
                    }
                });
        bootstrap.bind(port).sync().channel().closeFuture().syncUninterruptibly().await();

        System.out.println("UDP Server : [successfully started]");
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        defaultEventLoopGroup.shutdownGracefully();
    }
}

有人对如何正确关闭Netty udp服务器有任何想法吗?

2 个答案:

答案 0 :(得分:1)

首先,我假设您使用的git repo编写得很糟糕。此外,我建议不要使用它,因为UDP不打算在服务器/客户端模型中使用,并且回购协议所做的只是对您的UDP通道进行管理,因为UDP是无连接的。它真正要做的只是存储一个伪造的通道实例,该实例的核心只是一个NODE_PATH=src/。相反,您可以做的是对要缓存的其他InetAddress使用普通的线程安全List或某种存储方式。

但是,如果您确实需要使用此回购协议,则您需要停止InetAddress实例,因为ServerChannel启动了一个新的事件循环,该事件循环不暴露于外界,只能在关闭该循环时停止。渠道。 (这是您不应该使用它的另一个原因,对于同一件事打开多个UdpServerChannel是浪费的)

答案 1 :(得分:0)

我想我建立了另一种解决方法。 解决我的问题的方法,它不是完美,但它可以满足我的要求。

public class UdpServer {

private int port;
private UDPViewModel viewModel;
private final EventLoopGroup nioEventLoopGroup;
private ChannelFuture channelFuture;

public UdpServer(UDPViewModel viewModel, int port) {
   this.port = port;
   this.viewModel = viewModel;
    nioEventLoopGroup = new NioEventLoopGroup();
}

public void run() {
    System.out.println("UDP Server is starting.");
    try{
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(nioEventLoopGroup)
                .channel(NioDatagramChannel.class)
                .handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel channel) {
                        channel.pipeline().addLast(
                                new LoggingHandler(LogLevel.INFO),
                                new StringEncoder(), new StringDecoder());
                        channel.pipeline().addLast(
                                new UdpServerHandler(viewModel));
                    }
                });
        channelFuture = bootstrap.bind(port).sync();

    }
    catch (InterruptedException e) {
        System.err.println("UDP listener was interrupted and shutted down");
        e.getCause();
    }
}

public void StopServer()
{
    try {
        nioEventLoopGroup.shutdownGracefully().sync();
        channelFuture.channel().closeFuture().sync();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}