Netty shutdown / Stop UDP server - PullRequest
       35

Netty shutdown / Stop UDP server

0 голосов
/ 22 октября 2018

Я пытаюсь создать Netty UDP слушатель.Проблема, с которой я столкнулся, заключается в том, что я не могу остановить сервер udp, такой как tcp, udp всегда работает, даже если shutdowngraceful вызывается, единственный способ остановить это - вызвать исключение.

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 голосов
/ 23 октября 2018

Полагаю, я нашел другой способ решить эту проблему.Решение моей проблемы, это не ИДЕАЛЬНО , но оно делает то, что я хочу.

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();
    }
}
}
0 голосов
/ 22 октября 2018

Перво-наперво, я предполагаю, что вы используете это git repo , которое, кстати, довольно плохо написано.Более того, я бы рекомендовал не использовать его, поскольку UDP не предназначен для использования в модели сервер / клиент, и все, что делает репо, - это управление вашими каналами UDP, которых нет, поскольку UDP не имеет соединения.Все, что он на самом деле делает, - это сохраняет поддельный экземпляр канала, который по своей сути является InetAddress.Вместо этого вы можете использовать обычный потокобезопасный List или какой-то другой Storage для различных InetAddress, которые вы хотите кэшировать, и просто использовать это.

Но если вам действительно нужно использовать этот репозиторий, вам нужноостановить экземпляр ServerChannel, поскольку UdpServerChannel запускает новый цикл событий, который не отображается снаружи и может быть остановлен только при закрытии канала.(Это еще одна причина, по которой вы не должны его использовать, расточительно открывать несколько EventLoopGroups для одной и той же вещи)

...