简体   繁体   English

Netty关闭/停止UDP服务器

[英]Netty shutdown/Stop UDP server

I'm trying to create Netty UDP listener. 我正在尝试创建Netty UDP侦听器。 The problem I faced is that I can't stop udp server like tcp, the udp always is running, even with shutdowngracefully called, the only way to stop it is by throwing exception. 我面临的问题是我无法像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();
    }
}

Anyone has any ideas on how to shutdown netty udp server properly ? 任何人都对如何正确关闭Netty udp服务器有任何想法?

First things first, I'm assuming you use this git repo which by the way is pretty poorly written. 首先,我假设您使用的是这个git repo ,顺便说一句,它写得很差。 Furthermore I would recommend to not use it since UDP isn't intended to be used in a server/client model and all that repo does is manage your UDP channels which are not existent since UDP is connectionless. 此外,我建议不要使用它,因为不打算在服务器/客户端模型中使用UDP,并且回购协议所做的就是管理您的UDP通道,因为UDP是无连接的,所以不存在该通道。 All it really does is to store a fake channel instance which in its core is just a InetAddress . 它真正要做的就是存储一个假通道实例,该实例的核心只是一个InetAddress What you could do instead is to use a normal thread safe List or somesorte of Storage for the different InetAddress you wanna cache and just use this. 相反,您可以使用普通的线程安全List或某种存储方式来存储要缓存的其他InetAddress ,并仅使用它。

But if you really need to use this repo you need to stop the ServerChannel instance since the UdpServerChannel starts a new eventloop which isn't exposed to the outside and can only be stopped when closing the channel. 但是,如果您确实需要使用此存储库,则需要停止ServerChannel实例,因为UdpServerChannel启动了一个新的UdpServerChannelUdpServerChannel不暴露于外部,只能在关闭通道时停止。 (This is another reason you shouldn't use it, it's wasteful to open multiple EventLoopGroups for the same thing) (这是您不应该使用它的另一个原因,为同一件事打开多个EventLoopGroups是浪费的)

I guess I founded another way to solve this. 我想我找到了另一种方法来解决这个问题。 A solution to my problem, It's not PERFECT but it does what I want. 解决我的问题的方法,它不是完美的,但是可以满足我的要求。

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();
    }
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM