以编程方式关闭netty
我正在使用netty 4.0.24.Final。
我需要以编程方式启动/停止netty服务器。
启动服务器时,线程被阻止
f.channel().closeFuture().sync()
请帮助提供一些提示如何正确执行此操作。 下面是Main类调用的EchoServer。 谢谢。
package nettytests; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; public class EchoServer { private final int PORT = 8007; private EventLoopGroup bossGroup; private EventLoopGroup workerGroup; public void start() throws Exception { // Configure the server. bossGroup = new NioEventLoopGroup(1); workerGroup = new NioEventLoopGroup(1); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 100) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new EchoServerHandler()); } }); // Start the server. ChannelFuture f = b.bind(PORT).sync(); // Wait until the server socket is closed. Thread gets blocked. f.channel().closeFuture().sync(); } finally { // Shut down all event loops to terminate all threads. bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public void stop(){ bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } package nettytests; public class Main { public static void main(String[] args) throws Exception { EchoServer server = new EchoServer(); // start server server.start(); // not called, because the thread is blocked above server.stop(); } }
更新:我以下列方式更改了EchoServer类。 我们的想法是在新线程中启动服务器并保留指向EventLoopGroups的链接。 这是正确的方法吗?
package nettytests; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; /** * Echoes back any received data from a client. */ public class EchoServer { private final int PORT = 8007; private EventLoopGroup bossGroup; private EventLoopGroup workerGroup; public void start() throws Exception { new Thread(() -> { // Configure the server. bossGroup = new NioEventLoopGroup(1); workerGroup = new NioEventLoopGroup(1); Thread.currentThread().setName("ServerThread"); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 100) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new EchoServerHandler()); } }); // Start the server. ChannelFuture f = b.bind(PORT).sync(); // Wait until the server socket is closed. f.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { // Shut down all event loops to terminate all threads. bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }).start(); } public void stop() throws InterruptedException { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } }
一种方法是做一些像:
// once having an event in your handler (EchoServerHandler) // Close the current channel ctx.channel().close(); // Then close the parent channel (the one attached to the bind) ctx.channel().parent().close();
这样做将最终得到以下结果:
// Wait until the server socket is closed. Thread gets blocked. f.channel().closeFuture().sync();
主要部分无需额外的线程。 现在的问题是:什么样的事件? 这取决于你……可能是echo处理程序中的一条消息“shutdown”,它将被视为关闭的顺序,而不仅仅是“退出”,它将变为仅关闭客户端通道。 可能是别的……
如果你没有从子通道(通过你的处理程序)处理关闭,而是通过另一个进程(例如查找存在的停止文件),那么你需要一个额外的线程来等待这个事件,然后直接建立一个channel.close()
其中channel将是父节点(例如来自f.channel()
)…
存在许多其他解决方案
- 我们可以使用double来存储货币字段并使用BigDecimal进行算术运算
- 使用java websocket API和Javascript上传文件
- 制作一个显示“请等待”JDialog的摇摆线程
- 为什么Thread.isInterrupted()总是返回false?
- 根据哈希确认文件内容
- 解析数据时出错org.json.JSONException:在Android的字符0处输入结束
- 何时使用google Gson的tojson方法接受类型作为参数? public String toJson(Object src,Type typeOfSrc)
- 摆动鼠标听众被儿童组件拦截
- 从java调用shell,它抱怨“stty:标准输入:无效的参数”