【问题标题】: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)
            }
        }
    }

【问题讨论】:

    标签: kotlin netty ktor


    【解决方案1】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-15
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 2019-04-03
      • 2010-12-20
      • 1970-01-01
      相关资源
      最近更新 更多