我需要对Ktor应用程序进行一些初始化,但是我只想在Netty准备好接受连接之后再进行。另一方面,如果Netty无法启动(例如,典型的“地址已在使用中”),我不希望进行此类初始化。
我实现了简单的方法(请参见下文),但我想知道是否有可能使它变得不太丑陋?
首先,我将引用保存到NettyApplicationEngine:
embeddedServer = embeddedServer(Netty, port, module)
然后,我使用channels
NettyApplicationEngine中的字段来确定其状态:
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)
}
}
}
在尝试了几种不同的方法之后,我得出了一个自测结论,该测验仅将HTTP请求发送到我自己的端点,并且如果HttpClient和路由处理程序都成功执行,我认为Netty已经准备就绪。
首先,我向注册Routing.RoutingCallFinished
事件NettyApplicationEngine.environment.monitor
(dispose
稍后创建的处理程序)。
然后,我将全部迭代NettyApplicationEngine.environment.connectors
并创建Deferred
将从RoutingCallFinished
处理程序完成的。此外,我启动了异步协程,这些协程将使用HttpClient检查相应的端点。
从那以后,我awaitAll
对这些Deferred
S(以及Deferred
从ApplicationStarted
事件处理为好)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句