I'm currently trying to come up with a good multip...
# javascript
e
I'm currently trying to come up with a good multiplatform socket API. On the JS/Node side there is some trade off in terms of internal implementation
Copy code
actual fun connect(host: String, port: Int, listener: Result<ServerProperties>) {
  GlobalScope.launch {
    connectAsync(port, host).await()            // Await a JS promise
    val length = readUnsignedIntAsync().await() // Await a JS promise
    val data = readStringAsync(length).await()  // Await a JS promise
    val serverProperties = ServerProperties(data)
    listener.onSuccess(serverProperties)
  }
}
Would the above code be considered "ok"?
t
connectAsync
- custom function?
e
@turansky yes, it's a function that return a
Promise
, that I coded myself in Kotlin
t
Why it’s not
suspend
fun?
e
@turansky it uses the Node's Socket class, this is it
Copy code
private fun connectAsync(port: Int, host: String): Promise<Any?> =
  Promise { resolve, reject ->
    val errorHandler: (Error) -> Unit = {
      socket.removeAllListeners(Event.CONNECT)
      reject(it)
    }
    val connectHandler = {
      socket.removeListener(Event.ERROR, errorHandler)
      resolve(null)
    }
    socket.once(Event.ERROR, errorHandler)
    socket.setKeepAlive(true)
    socket.setTimeout(1000)
    socket.connect(port, host, connectHandler)
  }
Not sure if it's doable with coroutines
t
It’s definetely possible 🙂
👀 1
Even more elegant
cc @Sergei Grishchenko
e
Maybe I'm too new to coroutines, totally possible
maybe using
suspendCancellableCoroutine
is an option? So I don't have to use the JS promise
New version of
connectAsync
. This avoids using
await
, and propagating the same concept to writing and reading bytes avoids the Promise's
then
usages
Copy code
private suspend fun connectAsync(port: Int, host: String) {
  suspendCancellableCoroutine { continuation ->
    val errorHandler: (Error) -> Unit = {
      socket.removeAllListeners(Event.CONNECT)
      continuation.resumeWithException(it)
    }

    val connectHandler = {
      socket.removeListener(Event.ERROR, errorHandler)
      continuation.resume(Unit)
    }

    socket.once(Event.ERROR, errorHandler)
    socket.setKeepAlive(true)
    socket.setTimeout(1000)
    socket.connect(port, host, connectHandler)
  }
}
Is that what you meant when you said it was possible? Just for confirmation that I'm not doing wrong stuff lol
t
on and once - can open
suspend
API without callbacks
e
@turansky so like this in KT?
Copy code
EventEmitter.once(socket, Event.ERROR)
image.png
t
Probably TS types are outdated
Also I saw
on
and
once
on the same level with
EventEmitter
(not checked)
PR also will be fine 🙂