使用Kotlin协程实现涉及状态机的握手过程

使用Kotlin协程实现涉及状态机的握手过程,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,我是Kotlin的新手,需要实现执行握手过程的代码。这意味着有输入输出数据和状态机。例如: class Handshake { fun readData(data: List<Byte>): Outcome { if (currentState == State.STATE_1) { if (inspectState1Data(data) == Result.INVALID) { return Outco

我是Kotlin的新手,需要实现执行握手过程的代码。这意味着有输入输出数据和状态机。例如:

class Handshake {
    fun readData(data: List<Byte>): Outcome {
        if (currentState == State.STATE_1) {
            if (inspectState1Data(data) == Result.INVALID) {
                return Outcome.NEED_MORE_DATA // 
            } else {
                currentState = State.STATE_2
                return Outcome.CALL_AGAIN
            }
        } else if (currentState == State.STATE_2) {
            when (inspectState2Data(data)) {
                Result.REQUIRES_EXTRA_INFO -> return Outcome.PROVIDE_EXTRA_INFO
                Result.INVALID -> return Outcome.FAILURE
            }
        }
    }
}
对我来说,第二种形式更具可读性,当然也适用于Kotlin协同程序基础设施,特别是在作业取消等细节方面。与另一种形式相比,该代码的外观也更加有序


但是,我不清楚
suspendUntilResumedWithData()
suspendUntilResumedWithExtraInfo()
会是什么样子。我确实知道Continuation对象,但不知道如何在这里正确使用它们。有什么建议吗?

所以状态2循环在1完成后开始,或者您想要并行分解并选择先到者?对。首先是状态1,然后是状态2。我认为您需要通道而不是循环,因为continuation只能恢复一次,并且用于包装异步调用,您不应该将continuation存储在外部。我以前考虑过通道,但不确定这些方法是否正确,还因为我可能需要执行更多的操作,而不仅仅是输入更多的数据。请参见上面示例中带有“extrainfo”的零件。所以,我也在考虑实现类似于示例中的东西。请参见
return suspendCoroutine{cont->nextStep=cont}
如何存储延续,以及在每个步骤之后如何生成新的延续。但你反对这样做?原因是什么?未生成延续,suspendCoroutine获取当前延续(当前coroutine块的)。一个意念被恢复,然后同样的意念在那里再次获得。您可以反编译到java以获得更好的映像。在创建协同路由的过程中会创建一个延续,比如从启动或异步块。所以状态2循环在1完成后开始,或者您希望并行分解并选择先到的那个?对。首先是状态1,然后是状态2。我认为您需要通道而不是循环,因为continuation只能恢复一次,并且用于包装异步调用,您不应该将continuation存储在外部。我以前考虑过通道,但不确定这些方法是否正确,还因为我可能需要执行更多的操作,而不仅仅是输入更多的数据。请参见上面示例中带有“extrainfo”的零件。所以,我也在考虑实现类似于示例中的东西。请参见
return suspendCoroutine{cont->nextStep=cont}
如何存储延续,以及在每个步骤之后如何生成新的延续。但你反对这样做?原因是什么?未生成延续,suspendCoroutine获取当前延续(当前coroutine块的)。一个意念被恢复,然后同样的意念在那里再次获得。您可以反编译到java以获得更好的映像。在创建协同程序(如从启动或异步块)的过程中会创建一个延续。
suspend fun processHandshake(): Boolean {
    // State 1

    while (true) {
        // Loop until we get valid data
        val data: List<Byte> = suspendUntilResumedWithData() // How would this look like in Kotlin?
        if (inspectState1Data(data) != Result.INVALID)
            break
    }

    // State 2

    while (true) {
        // Loop until we are done. If during the process we
        // require extra info, request one. In this state,
        // however, receiving invalid data is not recoverable,
        // we need to exit with failure instead.
        val data: List<Byte> = suspendUntilResumedWithData()
        when (inspectState2Data(data)) {
            Result.REQUIRES_EXTRA_INFO -> {
                val extraInfo: ExtraInfo = suspendUntilResumedWithExtraInfo()
                processExtraInfo(extraInfo)
            }
            Result.INVALID -> return false // Return false to indicate failure
        }
    }

    return true // Success - return true
}