微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尝试响应通过StateFlow传递的ApplicationCall对象后,接收ResponseAlreadySentException

如何解决尝试响应通过StateFlow传递的ApplicationCall对象后,接收ResponseAlreadySentException

我正在KTOR中测试事件驱动的体系结构。我的核心逻辑保存在一个类中,该类对StateFlow发出的不同事件类型做出反应。 EventGenerator将事件推送到StateFlow中,由Core拾取。

但是,当Core尝试响应嵌入在我的一个事件中的ApplicationCall时,我会收到ResponseAlreadySentException,但我不确定为什么会这样。如果我绕过StateFlow并直接从EventGenerator调用Core类,则不会发生这种情况。我没有在代码中的其他任何地方响应ApplicationCalls,并且已经用断点检查了唯一的.respond行没有被多次击中。

MyStateFlow类:

class MyStateFlow {
    val state: StateFlow<CoreEvent>
        get() = _state

    private val _state = MutableStateFlow<CoreEvent>(CoreEvent.nothingEvent)

    suspend fun update(event: CoreEvent) {
        _state.value = event
    }
}

我的核心课程:

class Core(
   myStateFlow: MyStateFlow,coroutineContext: CoroutineContext = SupervisorJob() + dispatchers.IO
) {

   init {
       Coroutinescope(coroutineContext).launch {
           myStateFlow.state.collect {
               onEvent(it)
           }
       }
   }

   suspend fun onEvent(event: CoreEvent) {
      when(event) {
         is FooEvent {
            event.call.respond(HttpStatusCode.OK,"bar")
         }
         ...
      }
   }
}

我的EventGenerators之一是我的KTOR Application类中的一条路线:

get("/foo") {
   myStateFlow.update(CoreEvent.FooEvent(call))
}

但是,在我的浏览器中点击/f00会返回ResponseAlreadySentExceptionjava.lang.UnsupportedOperationException显示以下消息:“无法再设置标题,因为响应已经完成”。当我尝试使用其他尝试的解决方案时,错误响应可能会在两者之间切换,但是它们似乎在说同样的事情:在我尝试致电call.respond(...)之前,呼叫已得到响应。

如果我改为更改路线以直接调用Core.onEvent(),则按/foo会在浏览器中返回“ bar”,这是预期的行为:

get("/foo") {
   core.onEvent(CoreEvent.FooEvent(call))
}

为完整起见,我的依赖版本为:

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10"

implementation "io.ktor:ktor-server-netty:1.4.1"

非常感谢您提供的任何见解。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。