【发布时间】: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)
}
}
}
【问题讨论】: