如何在 Ktor 内部检查 Netty 是不是实际启动?

Posted

技术标签:

【中文标题】如何在 Ktor 内部检查 Netty 是不是实际启动?【英文标题】:How to check inside Ktor that the Netty is actually started?如何在 Ktor 内部检查 Netty 是否实际启动? 【发布时间】:2019-09-22 05:13:42 【问题描述】:

我需要对我的 Ktor 应用程序进行一些初始化,但我只想在 Netty 准备好接受连接后进行。另一方面,如果 Netty 无法启动(例如,典型的“地址已在使用中”),我不希望发生这种初始化。

我实现了直截了当的方法(见下文),但我想知道是否有可能使其以不那么丑陋的方式

首先我保存对 NettyApplicationEngine 的引用:

embeddedServer = embeddedServer(Netty, port, module)

然后我使用来自 NettyApplicationEngine 的channels 字段来确定它的状态:

private fun NettyApplicationEngine.channelsReady(): Boolean 
    val channelsField = this::class.members.find  it.name == "channels" !!
    channelsField.isAccessible = true
    val channels = channelsField.call(this) as List<Channel>?
    return !channels.isNullOrEmpty() && channels.all  it.isActive 

最后,我捕捉到 ApplicationStarted 事件并旋转直到通道准备就绪:

environment.monitor.subscribe(ApplicationStarted) 
        thread(start = true, name = "real netty postinit") 
            for (i in 1..100) 
                TimeUnit.MILLISECONDS.sleep(100)
                if (embeddedServer.channelsReady()) break
            

            if (embeddedServer.channelsReady()) 
                // Initialization here
             else 
                // Server didn't start
                embeddedServer.stop(1, 1, TimeUnit.SECONDS)
            
        
    

【问题讨论】:

【参考方案1】:

在尝试了几种不同的方法后,我以自检结束,它只是将 HTTP 请求发送到我自己的端点,如果 HttpClient 和路由处理程序都成功执行,我认为 Netty 已经准备好了。

首先我向NettyApplicationEngine.environment.monitor 注册Routing.RoutingCallFinished 事件(稍后我将dispose 创建处理程序)。

然后我迭代所有NettyApplicationEngine.environment.connectors 并创建Deferreds,它将从RoutingCallFinished 处理程序中完成。另外,我启动了异步协程,它将使用 HttpClient 检查相应的端点。

之后我在那些Deferreds 上awaitAll(以及来自ApplicationStarted 事件处理程序的Deferred)。

【讨论】:

以上是关于如何在 Ktor 内部检查 Netty 是不是实际启动?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 io.ktor.server.engine.CommandLineKt 在 gradle/kotlin/netty 项目中抛出的“既未指定端口也未指定 sslPort”?

如何在 Ktor 内部重定向?

Ktor Netty 服务器发送空响应

gRPC over TLS 使用 Netty/Kortlin/Ktor 引发错误并阻止 gNMI 工作

使用 ktor 检查多部分请求正文中是不是存在所有参数

如何在 IntelliJ IDEA 中为 Ktor 设置运行配置?