如何用Kotlin的协程替换create java Thread?

时间:2019-04-26 12:20:35

标签: kotlin-coroutines

我是Kotlin协程中的新手。

此处使用经典的线程代码:

 import com.google.gson.JsonElement
    import com.google.gson.JsonObject
    import com.google.gson.JsonParser
    import com.zaxxer.hikari.HikariConfig
    import com.zaxxer.hikari.HikariDataSource
    import okhttp3.*
    import okio.ByteString
    import org.slf4j.LoggerFactory
    import java.util.concurrent.atomic.AtomicInteger

    object BithumbSocketListener : WebSocketListener() {

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            super.onFailure(webSocket, t, response)
            Thread {
                оkHttpClient.newWebSocket(wsRequest, BithumbSocketListener)
            }.start()
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            super.onMessage(webSocket, text)
            logger.debug("ws_onMessage: text = $text")
        }

    }

    fun main(args: Array<String>) {
        currenciesList = currencies.split(",")
        currenciesList.forEach {
            OkHttpClient().newWebSocket(wsRequest, BithumbSocketListener)
        }
    } 

如您所见,我有货币列表(currenciesList)。我对其进行迭代,并为列表的每个项目调用newWebSocket。如您所见,BithumbSocketListener单个

如果Web套接字有问题,请调用回调方法onFailure,然后在单独的Java线程中创建新的Web套接字:

        Thread {
            оkHttpClient.newWebSocket(wsRequest, BithumbSocketListener)
}.start()

好。很好 但是我想用 Kotlin协程代替此代码。 我该怎么做?

谢谢。

1 个答案:

答案 0 :(得分:1)

由于您正在处理异步消息流,因此应通过实现actor将其移植到协程中,例如

val wsActor: SendChannel<String> = actor {
    for (msg in channel) {
        logger.info("Another message is in: ${msg}")
    }
}

wsActor的类型中可以看到应该向其发送消息。这是桥接代码的来源:

class BithumbSocketListener(
    private val chan: Channel<String>
) : WebSocketListener() {
    override fun onMessage(webSocket: WebSocket, text: String) {
        chan.send(text)
    }

    override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
        оkHttpClient.newWebSocket(wsRequest, this)
    }
}

请注意,与您的代码相比,我不会启动任何新线程进行重试。这与移植到协程无关,您的代码也不需要它。 newWebSocket是立即返回的异步调用。

最后,启动每种货币的网络套接字:

currenciesList.forEach {
    OkHttpClient().newWebSocket(wsRequest, BithumbSocketListener(wsActor)
}