以编程方式关闭 netty

2023-12-25

我正在使用 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<SocketChannel>() {
                 @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();
    }
}

UPDATE:我通过以下方式更改了 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<SocketChannel>() {
                            @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();

主要部件上不需要额外的螺纹。 现在的问题是:什么样的事件?这取决于你......回显处理程序中可能有一条消息作为“关闭”,该消息将被视为关闭命令,而不仅仅是“退出”,后者将仅视为关闭客户端通道。可能还有别的事...

如果您不处理从子通道(因此通过您的处理程序)的关闭,而是通过另一个进程(例如查找现有的停止文件),那么您需要一个额外的线程来等待此事件,然后直接创建一个channel.close()其中通道将是父通道(来自f.channel()) 例如...

存在许多其他解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以编程方式关闭 netty 的相关文章

随机推荐

  • gpuDevice() 工具包版本始终为 5.5

    无论我如何重新安装CUDA驱动程序和工具包 当输入gpuDevice 时 它总是显示 CUDADevice with properties Name Quadro K2000M Index 1 ComputeCapability 3 0 S
  • 删除/清空的 Graphite Whisper 文件自动重新生成

    我试图删除一些旧的石墨测试耳语指标 但没有成功 我可以通过删除文件来删除指标 看 如何清理石墨耳语的数据 https stackoverflow com questions 9587161 how to cleanup the graphi
  • 如何使用 Gitlab 设置代码审查?

    如何使用 Gitlab 设置代码审查 我看到它在 Gitlab 网站上被列为一项功能 但我似乎找不到有关如何设置该功能的说明 就这一点而言 任何指向 Gitlab 用户手册的链接将不胜感激 我的一些搜索表明 合并请求 是可行的方法 但我发现
  • 从命令行启动 AVD 时卡在“撤销 Google 应用程序的麦克风权限”上

    我正在运行命令来启动 AVD 但是 当设备启动时 卡在这个错误上 撤销 Google 应用的麦克风权限 有什么线索吗 我正在使用 AVD 设备 API 28 运行这些命令时出现同样的错误 Users username Library And
  • 了解 WCF

    谁能给我指出一个用图片和简单代码片段解释 WCF 的资源 我厌倦了在所有搜索结果中进行谷歌搜索并找到相同的 ABC 文章 WCF 是一项非常复杂的技术 在我看来 它的文档记录非常少 它的启动和运行非常容易 但是运行大型应用程序的性能调整可能
  • 如何使用 dalli 和 Rails 将内存缓存板大小增加到 1MB 以上?

    我正在使用 Ruby on Rails 和 dalli gem 通过 memcache 进行缓存 默认值 键值存储中的值 又名slab 最大大小为1MB 我想将其增加到 2MB dalli 的文档 https stackoverflow c
  • 无法找到名为“entityManagerFactory”的 bean

    我的应用程序无法启动 它由 Spring Boot JPA SQLite 组成 但 Spring Boot 和 MySQL 运行良好 我不明白为什么会发生这种情况 错误是 无法找到名为 entityManagerFactory 的 bean
  • Stripe 在 Python 中不会抛出充电错误

    我正在使用 Python 中的 stripe 库进行信用卡收费 我使用 customerID 来收费 而不是使用令牌 因为我想重复使用该卡 而无需每次都询问 成功过程运行得很好 但是 如果我创建错误条件 则永远不会抛出 例外 我正在使用无效
  • Javascript document.cookie 总是返回空字符串

    我在客户端 javascript 设置 cookie 时遇到了这个真正奇怪的问题 我目前正在开发一个小型的 1 页演示 以使用 cookie 来存储一些 首选项 请注意 我无法在此演示中使用服务器端语言或任何第 3 方 jQuery 插件
  • 尝试使用 python 3 加载 JSON 对象时出错

    我有以下 json 对象 我试图用 python 3 解析 customerData Joe visits 1 Carol visits 2 Howard visits 3 Carrie visits 4 我使用以下 python 代码来解
  • 等待任务.Delay(foo);需要几秒而不是毫秒

    使用可变延迟Task Delay当与类似 IO 的操作结合时 随机花费几秒而不是几毫秒 重现代码 using System using System Collections Generic using System Diagnostics
  • React-js 忽略标签的 'for' 属性

    我知道对于 class 我们必须使用 className 但是我如何做出反应以保留 for 属性 下列
  • 在循环中定义匿名函数(包括循环变量)?

    我知道这段代码不起作用 我也知道为什么 但是 我不知道如何解决它 JavaScript var function id return document getElementById id document addEventListener
  • 如何从我的网站邀请 Facebook 的朋友 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • SQL Server 2008 R2(.Net 2.0 应用程序)中的死锁问题

    所讨论的 Sql Server 2008 R2 实例是一个重负载 OLTP 生产服务器 几天前出现了僵局问题 但仍未解决 我们收到了 Xml 死锁报告 其中列出了死锁涉及的存储过程以及其他一些详细信息 我将首先尝试列出此 xml 中的事实
  • iOS 开发者版本与发行版版本

    一段时间以来 我一直有这样的印象 对于 iOS 使用开发人员配置文件签署构建允许应用程序通过 XCode 构建在授权设备 在开发配置文件中列出 上运行 并进行调试 而使用分发配置文件签名允许应用程序在其他 iOS 设备上运行 但不能调试 这
  • 在 PhoneGap 1.2.0 中使用 Google Analytics 时 Android 和 iOS 之间的差异

    我一直在尝试让 Google Analytics 在 Android 和 iOS 上的 PhoneGap 1 2 0 中工作 在 PhoneGap 1 2 0 中使用 Google Analytics 时 Android 和 iOS 之间的
  • 使用 jquery ajax 在同一 POST 请求中上传文件和 JSON 数据?

    我正在尝试使用 jQuery Ajax 发送 POST 请求 我想在其中上传文件和一些 json 数据 请查找代码 var logoImg input name logoImg get 0 files 0 var formData new
  • Jinja2 中的独特列表过滤器

    我有以下 YAML 结构 bri cards slot 1 subslot 0 ports 2 slot 1 subslot 1 ports 2 slot 1 subslot 2 ports 2 slot 2 subslot 0 ports
  • 以编程方式关闭 netty

    我正在使用 netty 4 0 24 Final 我需要以编程方式启动 停止 netty 服务器 启动服务器时 线程被阻塞在 f channel closeFuture sync 请帮助提供一些如何正确执行的提示 下面是 Main 类调用的