Handling application-level events

预计阅读时间:2分钟

在服务器端,除了处理请求外,Ktor还公开了一种机制来生成和使用全局事件.

例如,当应用程序正在启动,启动或停止时,将生成并引发事件. 您可以订阅或取消订阅这些事件并触发代码执行. 与应用程序环境关联的monitor: ApplicationEvents实例充当事件分发程序.

ApplicationEvents调度类型为EventDefinition<T>的对象T

您可以通过执行application.environment.monitor来获得监视器和应用程序实例.

ApplicationEvents API

monitor: ApplicationEvents的简化API monitor: ApplicationEvents如下所示:

class ApplicationEvents {
    fun <T> subscribe(definition: EventDefinition<T>, handler: EventHandler<T>): DisposableHandle
    fun <T> unsubscribe(definition: EventDefinition<T>, handler: EventHandler<T>)
    fun <T> raise(definition: EventDefinition<T>, value: T)
}

class EventDefinition<T>

typealias EventHandler<T> = (T) -> Unit

interface DisposableHandle {
    fun dispose()
}

Predefined EventDefinitions

Ktor提供了一些由引擎调度的预定义事件:

val ApplicationStarting: EventDefinition<Application>
val ApplicationStarted: EventDefinition<Application>
val ApplicationStopPreparing: EventDefinition<ApplicationEnvironment>
val ApplicationStopping: EventDefinition<Application>
val ApplicationStopped: EventDefinition<Application>

Subscribing to events and raising them

您可以通过从监视器调用subscribe方法来订阅事件. subscription方法返回一个DisposableHandle ,您可以调用该DisposableHandle取消订阅. 此外,您可以使用相同的方法句柄调用unsubscribe方法以取消订阅.

使用一次性用品:

val disposable = application.environment.monitor.subscribe(ApplicationStarting) { application: Application ->
    // Handle the event using the application as subject
}
disposable.dispose() // Cancels the subscription

使用存储在属性中的lambda:

val starting: (Application) -> Unit = { log("Application starting: $it") }

application.environment.monitor.subscribe(ApplicationStarting, starting) // subscribe
application.environment.monitor.unsubscribe(ApplicationStarting, starting) // unsubscribe

使用方法参考:

fun starting(application: Application) { log("Application starting: $it") }

application.environment.monitor.subscribe(ApplicationStarting, ::starting) // subscribe
application.environment.monitor.unsubscribe(ApplicationStarting, ::starting) // unsubscribe

如果要创建自定义事件并调度或引发它们:

class MySubject
val MyEventDefinition = EventDefinition<MySubject>()
monitor.raise(MyEventDefinition, MySubject())

Examples

您可以检查CallLogging功能源代码 ,其中包括订阅应用程序中事件的代码.

by  ICOPY.SITE