Как заменить создание Java Thread на сопрограммы Kotlin? - PullRequest
0 голосов
/ 26 апреля 2019

Я новичок в сопрограммах Котлина.

Здесь код с классической Тема :

 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 является синглтоном .

Если есть проблемы с веб-сокетом, тогда вызовите метод обратного вызова onFailure, и я создаю новый веб-сокет в отдельном потоке Java:

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

Приятно.Это нормально работает.Но я хочу заменить этот код на Котлин сопрограммы .Как я могу это сделать?

Спасибо.

1 Ответ

1 голос
/ 26 апреля 2019

Поскольку вы обрабатываете асинхронный поток сообщений, вы должны перенести его на сопрограммы, внедрив актера, такого как

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 - это асинхронный вызов, который немедленно возвращается.

Наконец, запустите websockets для каждой валюты:

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