Skip to content

Instantly share code, notes, and snippets.

@omarmiatello
Last active June 4, 2024 13:37
Show Gist options
  • Save omarmiatello/2ada5872fd13f4ef7ae28f7fc19b4019 to your computer and use it in GitHub Desktop.
Save omarmiatello/2ada5872fd13f4ef7ae28f7fc19b4019 to your computer and use it in GitHub Desktop.
First experiment with WebSocket and Kotlin Coroutine

First experiment with WebSocket and Kotlin Coroutine

output:

main Start!
[job1] Open: Response{protocol=http/1.1, code=101, message=Web Socket Protocol Handshake, url=http://echo.websocket.org/}
[job2] Open: Response{protocol=http/1.1, code=101, message=Web Socket Protocol Handshake, url=http://echo.websocket.org/}
[job1] --> Hi, I am job1 @ 1!
[job2] --> Hi, I am job2 @ 1!
[job2] <-- Hi, I am job2 @ 1!
[job1] <-- Hi, I am job1 @ 1!
[job1] --> Hi, I am job1 @ 2!
[job2] --> Hi, I am job2 @ 2!
[job2] <-- Hi, I am job2 @ 2!
[job1] <-- Hi, I am job1 @ 2!
[job1] --> Hi, I am job1 @ 3!
[job2] --> Hi, I am job2 @ 3!
[job2] <-- Hi, I am job2 @ 3!
[job1] <-- Hi, I am job1 @ 3!
[job2] Finish!
[job1] Finish!
main Finish!

Process finished with exit code 0
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.launch
import okhttp3.*
import okio.ByteString
import kotlin.coroutines.experimental.suspendCoroutine
/**
* Created by omarmiatello on 17/06/17.
*/
class EasyWS(val webSocket: WebSocket, val response: Response) {
val textChannel = Channel<String>()
}
suspend fun OkHttpClient.easyWebSocket(url: String) = suspendCoroutine<EasyWS> {
var easyWs: EasyWS? = null
newWebSocket(Request.Builder().url(url).build(), object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
// println("onOpen: $response")
easyWs = EasyWS(webSocket, response)
it.resume(easyWs!!)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
it.resumeWithException(t)
// println("onFailure: $t $response")
}
override fun onClosing(webSocket: WebSocket, code: Int, reason: String?) {
// println("onClosing: $code $reason")
webSocket.close(1000, "Bye!")
}
override fun onMessage(webSocket: WebSocket, text: String) {
runBlocking { easyWs!!.textChannel.send(text) }
}
override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
// println("<--[B] $bytes")
}
override fun onClosed(webSocket: WebSocket, code: Int, reason: String?) {
// println("onClosed: $code $reason")
easyWs!!.textChannel.close()
}
})
}
import kotlinx.coroutines.experimental.*
import okhttp3.OkHttpClient
/**
* Created by omarmiatello on 16/06/17.
*/
val client = OkHttpClient()
fun main(args: Array<String>) = runBlocking {
println("main Start!")
val jobs = arrayListOf<Job>()
jobs += longJob("job1")
jobs += longJob("job2")
// jobs += longJob("job3")
jobs.forEach { it.join() }
client.dispatcher().executorService().shutdown()
println("main Finish!")
}
private fun longJob(jobName: String) = launch(CommonPool) {
val easyWS = client.easyWebSocket("ws://echo.websocket.org")
println("[$jobName] Open: ${easyWS.response}")
launch(context) {
for (i in 1..3) {
delay(1000) // every 1s
val msg = "Hi, I am $jobName @ $i!"
println("[$jobName] --> $msg")
easyWS.webSocket.send(msg)
}
easyWS.webSocket.close(1000, "Bye! $jobName")
}
for (msg in easyWS.textChannel) {
println("[$jobName] <-- $msg")
}
println("[$jobName] Finish!")
}
@omarmiatello
Copy link
Author

that's my build.gradle

buildscript {
    ext.kotlin_version = '1.1.2-5'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

apply plugin: 'java'
apply plugin: 'kotlin'

sourceCompatibility = 1.8

kotlin {
    experimental.coroutines 'enable'
}

repositories {
    mavenCentral()
    maven { url "https://dl.bintray.com/kotlin/kotlinx" }
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.16'

    compile 'com.squareup.okhttp3:okhttp:3.8.0'

    testCompile group: 'junit', name: 'junit', version: '4.12'
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment