我正在尝试创建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服务器有任何想法吗?
答案 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();
}
}
}