【问题标题】:Netty shutdown/Stop UDP serverNetty 关闭/停止 UDP 服务器
【发布时间】:2019-03-26 08:07:46
【问题描述】:

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

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 服务器有任何想法吗?

【问题讨论】:

    标签: java server udp netty shutdown


    【解决方案1】:

    首先,我假设您使用这个git repo,顺便说一句,它写得很糟糕。此外,我建议不要使用它,因为 UDP 不打算在服务器/客户端模型中使用,并且 repo 所做的只是管理您的 UDP 通道,这些通道不存在,因为 UDP 是无连接的。它真正做的只是存储一个假通道实例,其核心只是一个InetAddress。您可以做的是使用普通线程安全List 或某种存储来存储您想要缓存的不同InetAddress,然后使用它。

    但是如果你真的需要使用这个 repo,你需要停止 ServerChannel 实例,因为 UdpServerChannel 启动了一个新的事件循环,它不暴露在外部并且只能在关闭通道时停止。 (这是你不应该使用它的另一个原因,为同一件事打开多个EventLoopGroups很浪费)

    【讨论】:

    • 那么,netty 不适合 udp 服务器?难怪我找不到任何好的 netty 和 udp 样本...
    【解决方案2】:

    我想我找到了另一种方法来解决这个问题。 我的问题的解决方案,它不是完美,但它可以满足我的需求。

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

    【讨论】:

      猜你喜欢
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-01
      相关资源
      最近更新 更多