subscribe

expect inline fun <E : Event> subscribe(    coroutineContext: CoroutineContext = EmptyCoroutineContext,     concurrency: ConcurrencyKind = LOCKED,     priority: EventPriority = EventPriority.NORMAL,     noinline handler: suspend E.(E) -> ListeningStatus): Listener<E>

创建一个事件监听器, 监听事件通道中所有 E 及其子类事件.

每当 事件广播 时, handler 都会被执行.

创建监听

调用本函数:

eventChannel.subscribe<E> { /* 会收到此通道中的所有是 E 的事件 */}

生命周期

通过协程作用域管理监听器

本函数将会创建一个 Job, 成为 parentJob 中的子任务. 可创建一个 CoroutineScope 来管理所有的监听器:

val scope = CoroutineScope(SupervisorJob())

val scopedChannel = eventChannel.parentScope(scope) // 将协程作用域 scope 附加到这个 EventChannel

scopedChannel.subscribeAlways<MemberJoinEvent> { /* ... */} // 启动监听, 监听器协程会作为 scope 的子任务
scopedChannel.subscribeAlways<MemberMuteEvent> { /* ... */} // 启动监听, 监听器协程会作为 scope 的子任务

scope.cancel() // 停止了协程作用域, 也就取消了两个监听器

这个函数返回 Listener, 它是一个 CompletableJob. 它会成为 parentJobparentScope 的一个 子任务

停止监听

如果 handler 返回 ListeningStatus.STOPPED 监听器将被停止.

也可以通过 subscribe 返回值 ListenerListener.complete

监听器调度

监听器会被创建一个协程任务, 语义上在 parentScope 下运行. 通过 Kotlin 默认协程调度器 在固定的全局共享线程池里执行, 除非有 coroutineContext 指定.

默认在 handler 中不能处理阻塞任务. 阻塞任务将会阻塞一个 Kotlin 全局协程调度线程并可能导致严重问题. 请通过 withContext(Dispatchers.IO) { } 等方法执行阻塞工作.

异常处理

监听过程抛出的异常是需要尽可能避免的, 因为这将产生不确定性.

当参数 handler 处理事件抛出异常时, 只会从监听方协程上下文 (CoroutineContext) 寻找 CoroutineExceptionHandler 处理异常, 即如下顺序:

  1. 本函数参数 coroutineContext

  2. EventChannel.defaultCoroutineContext

  3. 若以上步骤无法获取 CoroutineExceptionHandler, 则只会在日志记录异常. 因此建议先指定 CoroutineExceptionHandler (可通过 EventChannel.exceptionHandler) 再监听事件, 或者在监听事件中捕获异常.

因此, 广播方 (Event.broadcast) 不会知晓监听方产生的异常, 其 Event.broadcast 过程也不会因监听方产生异常而提前结束.

备注: 在 2.11 以前, 发生上述异常时还会从广播方和有关 Bot 协程域获取 CoroutineExceptionHandler. 因此行为不稳定而在 2.11 变更为上述过程.

事件处理时抛出异常不会停止监听器.

建议在事件处理中 (即 handler 里) 处理异常, 或在参数 coroutineContext 中添加 CoroutineExceptionHandler, 或通过 EventChannel.exceptionHandler.

并发安全性

基于 concurrency 参数, 事件监听器可以被允许并行执行.

衍生监听方法

这些方法仅 Kotlin 可用.

  • syncFromEvent: 挂起当前协程, 监听一个事件, 并尝试从这个事件中获取一个值

  • nextEvent: 挂起当前协程, 直到监听到特定类型事件的广播并通过过滤器, 返回这个事件实例.

Return

监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 handler

See also

when 的语法 '选择' 即将到来的一条消息.

when 的语法 '选择' 即将到来的所有消息, 直到不满足筛选结果.

监听消息 DSL

Parameters

coroutineContext

defaultCoroutineContext 的基础上, 给事件监听协程的额外的 CoroutineContext.

concurrency

并发类型. 查看 ConcurrencyKind

priority

监听优先级,优先级越高越先执行

handler

事件处理器. 在接收到事件时会调用这个处理器. 其返回值意义参考 ListeningStatus. 其异常处理参考上文


expect fun <E : Event> subscribe(    eventClass: KClass<out E>,     coroutineContext: CoroutineContext = EmptyCoroutineContext,     concurrency: ConcurrencyKind = LOCKED,     priority: EventPriority = EventPriority.NORMAL,     handler: suspend E.(E) -> ListeningStatus): Listener<E>

subscribe 的区别是接受 eventClass 参数, 而不使用 reified 泛型. 通常推荐使用具体化类型参数.

Return

监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 handler

See also

fun <E : Event> subscribe(    eventClass: Class<out E>,     coroutineContext: CoroutineContext = EmptyCoroutineContext,     concurrency: ConcurrencyKind = CONCURRENT,     priority: EventPriority = EventPriority.NORMAL,     handler: Function<E, ListeningStatus>): Listener<E>

Java API. 查看 subscribe 获取更多信息.

eventChannel.subscribe(GroupMessageEvent.class, (event) -> {
return ListeningStatus.LISTENING;
});

See also


actual inline fun <E : Event> subscribe(    coroutineContext: CoroutineContext,     concurrency: ConcurrencyKind,     priority: EventPriority,     noinline handler: suspend E.(E) -> ListeningStatus): Listener<E>

创建一个事件监听器, 监听事件通道中所有 E 及其子类事件.

每当 事件广播 时, handler 都会被执行.

创建监听

调用本函数:

eventChannel.subscribe<E> { /* 会收到此通道中的所有是 E 的事件 */}

生命周期

通过协程作用域管理监听器

本函数将会创建一个 Job, 成为 parentJob 中的子任务. 可创建一个 CoroutineScope 来管理所有的监听器:

val scope = CoroutineScope(SupervisorJob())

val scopedChannel = eventChannel.parentScope(scope) // 将协程作用域 scope 附加到这个 EventChannel

scopedChannel.subscribeAlways<MemberJoinEvent> { /* ... */} // 启动监听, 监听器协程会作为 scope 的子任务
scopedChannel.subscribeAlways<MemberMuteEvent> { /* ... */} // 启动监听, 监听器协程会作为 scope 的子任务

scope.cancel() // 停止了协程作用域, 也就取消了两个监听器

这个函数返回 Listener, 它是一个 CompletableJob. 它会成为 parentJobparentScope 的一个 Job

停止监听

如果 handler 返回 ListeningStatus.STOPPED 监听器将被停止.

也可以通过 subscribe 返回值 Listener 的 Listener.complete

监听器调度

监听器会被创建一个协程任务, 语义上在 parentScope 下运行. 通过 Kotlin Dispatchers.Default 在固定的全局共享线程池里执行, 除非有 coroutineContext 指定.

默认在 handler 中不能处理阻塞任务. 阻塞任务将会阻塞一个 Kotlin 全局协程调度线程并可能导致严重问题. 请通过 withContext(Dispatchers.IO) { } 等方法执行阻塞工作.

异常处理

监听过程抛出的异常是需要尽可能避免的, 因为这将产生不确定性.

当参数 handler 处理事件抛出异常时, 只会从监听方协程上下文 (CoroutineContext) 寻找 CoroutineExceptionHandler 处理异常, 即如下顺序:

  1. 本函数参数 coroutineContext

  2. EventChannel.defaultCoroutineContext

  3. 若以上步骤无法获取 CoroutineExceptionHandler, 则只会在日志记录异常. 因此建议先指定 CoroutineExceptionHandler (可通过 EventChannel.exceptionHandler) 再监听事件, 或者在监听事件中捕获异常.

因此, 广播方 (Event.broadcast) 不会知晓监听方产生的异常, 其 Event.broadcast 过程也不会因监听方产生异常而提前结束.

备注: 在 2.11 以前, 发生上述异常时还会从广播方和有关 Bot 协程域获取 CoroutineExceptionHandler. 因此行为不稳定而在 2.11 变更为上述过程.

事件处理时抛出异常不会停止监听器.

建议在事件处理中 (即 handler 里) 处理异常, 或在参数 coroutineContext 中添加 CoroutineExceptionHandler, 或通过 EventChannel.exceptionHandler.

并发安全性

基于 concurrency 参数, 事件监听器可以被允许并行执行.

衍生监听方法

这些方法仅 Kotlin 可用.

  • syncFromEvent: 挂起当前协程, 监听一个事件, 并尝试从这个事件中获取一个值

  • nextEvent: 挂起当前协程, 直到监听到特定类型事件的广播并通过过滤器, 返回这个事件实例.

Return

监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 handler

See also

when 的语法 '选择' 即将到来的一条消息.

when 的语法 '选择' 即将到来的所有消息, 直到不满足筛选结果.

监听消息 DSL

Parameters

coroutineContext

defaultCoroutineContext 的基础上, 给事件监听协程的额外的 CoroutineContext.

concurrency

并发类型. 查看 ConcurrencyKind

priority

监听优先级,优先级越高越先执行

handler

事件处理器. 在接收到事件时会调用这个处理器. 其返回值意义参考 ListeningStatus. 其异常处理参考上文


actual fun <E : Event> subscribe(    eventClass: KClass<out E>,     coroutineContext: CoroutineContext,     concurrency: ConcurrencyKind,     priority: EventPriority,     handler: suspend E.(E) -> ListeningStatus): Listener<E>

subscribe 的区别是接受 eventClass 参数, 而不使用 reified 泛型. 通常推荐使用具体化类型参数.

Return

监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 handler

See also

actual inline fun <E : Event> subscribe(    coroutineContext: CoroutineContext,     concurrency: ConcurrencyKind,     priority: EventPriority,     noinline handler: suspend E.(E) -> ListeningStatus): Listener<E>

创建一个事件监听器, 监听事件通道中所有 E 及其子类事件.

每当 事件广播 时, handler 都会被执行.

创建监听

调用本函数:

eventChannel.subscribe<E> { /* 会收到此通道中的所有是 E 的事件 */}

生命周期

通过协程作用域管理监听器

本函数将会创建一个 Job, 成为 parentJob 中的子任务. 可创建一个 CoroutineScope 来管理所有的监听器:

val scope = CoroutineScope(SupervisorJob())

val scopedChannel = eventChannel.parentScope(scope) // 将协程作用域 scope 附加到这个 EventChannel

scopedChannel.subscribeAlways<MemberJoinEvent> { /* ... */} // 启动监听, 监听器协程会作为 scope 的子任务
scopedChannel.subscribeAlways<MemberMuteEvent> { /* ... */} // 启动监听, 监听器协程会作为 scope 的子任务

scope.cancel() // 停止了协程作用域, 也就取消了两个监听器

这个函数返回 Listener, 它是一个 CompletableJob. 它会成为 parentJobparentScope 的一个 子任务

停止监听

如果 handler 返回 ListeningStatus.STOPPED 监听器将被停止.

也可以通过 subscribe 返回值 ListenerListener.complete

监听器调度

监听器会被创建一个协程任务, 语义上在 parentScope 下运行. 通过 Kotlin 默认协程调度器 在固定的全局共享线程池里执行, 除非有 coroutineContext 指定.

默认在 handler 中不能处理阻塞任务. 阻塞任务将会阻塞一个 Kotlin 全局协程调度线程并可能导致严重问题. 请通过 withContext(Dispatchers.IO) { } 等方法执行阻塞工作.

异常处理

监听过程抛出的异常是需要尽可能避免的, 因为这将产生不确定性.

当参数 handler 处理事件抛出异常时, 只会从监听方协程上下文 (CoroutineContext) 寻找 CoroutineExceptionHandler 处理异常, 即如下顺序:

  1. 本函数参数 coroutineContext

  2. EventChannel.defaultCoroutineContext

  3. 若以上步骤无法获取 CoroutineExceptionHandler, 则只会在日志记录异常. 因此建议先指定 CoroutineExceptionHandler (可通过 EventChannel.exceptionHandler) 再监听事件, 或者在监听事件中捕获异常.

因此, 广播方 (Event.broadcast) 不会知晓监听方产生的异常, 其 Event.broadcast 过程也不会因监听方产生异常而提前结束.

备注: 在 2.11 以前, 发生上述异常时还会从广播方和有关 Bot 协程域获取 CoroutineExceptionHandler. 因此行为不稳定而在 2.11 变更为上述过程.

事件处理时抛出异常不会停止监听器.

建议在事件处理中 (即 handler 里) 处理异常, 或在参数 coroutineContext 中添加 CoroutineExceptionHandler, 或通过 EventChannel.exceptionHandler.

并发安全性

基于 concurrency 参数, 事件监听器可以被允许并行执行.

衍生监听方法

这些方法仅 Kotlin 可用.

  • syncFromEvent: 挂起当前协程, 监听一个事件, 并尝试从这个事件中获取一个值

  • nextEvent: 挂起当前协程, 直到监听到特定类型事件的广播并通过过滤器, 返回这个事件实例.

Return

监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 handler

See also

when 的语法 '选择' 即将到来的一条消息.

when 的语法 '选择' 即将到来的所有消息, 直到不满足筛选结果.

监听消息 DSL

Parameters

coroutineContext

defaultCoroutineContext 的基础上, 给事件监听协程的额外的 CoroutineContext.

concurrency

并发类型. 查看 ConcurrencyKind

priority

监听优先级,优先级越高越先执行

handler

事件处理器. 在接收到事件时会调用这个处理器. 其返回值意义参考 ListeningStatus. 其异常处理参考上文


actual fun <E : Event> subscribe(    eventClass: KClass<out E>,     coroutineContext: CoroutineContext,     concurrency: ConcurrencyKind,     priority: EventPriority,     handler: suspend E.(E) -> ListeningStatus): Listener<E>

subscribe 的区别是接受 eventClass 参数, 而不使用 reified 泛型. 通常推荐使用具体化类型参数.

Return

监听器实例. 此监听器已经注册到指定事件上, 在事件广播时将会调用 handler

See also