How to Serialize Web Socket Frame.text in Ktor with kotlinx.serialization

1.8k Views Asked by At
webSocket("/ws") {
            try {
                while (true) {
                    when(val frame = incoming.receive()){
                        is Frame.Text -> {
                            val text = frame.readText() //i want to Serialize it to class object
                            send(Frame.Text(processRequest(text)))
                        }
                        else -> TODO()
                    }
                }
            } finally {
                TODO()
            }
        }

i want to Serialize frame.readText() to return class object i'm totally new to Ktor world and i don't know if that is possible

1

There are 1 best solutions below

2
On BEST ANSWER

You can use the underlying kotlinx.serialization that you might have already set up for ContentNegotiation already. If you haven't, instructions can be found here. This will require to make your class (I assumed the name ObjectType) serializable with @Serializable. More details here on how to make a class serializable and also how to encode/decode to JSON format. I included the solution snippet:

webSocket("/ws") {
            try {
                while (true) {
                    when(val frame = incoming.receive()){
                        is Frame.Text -> {
                            val text = Json.decodeFromString<ObjectType>(frame.readText())
                            send(Frame.Text(processRequest(text)))
                        }
                        else -> TODO()
                    }
                }
            } finally {
                TODO()
            }
        }

I would usually use a flow (requires kotlinx.coroutines)

incoming.consumeAsFlow()
        .mapNotNull { it as? Frame.Text }
        .map { it.readText() }
        .map { Json.decodeFromString<ObjectType>(it) }
        .onCompletion {
            //here comes what you would put in the `finally` block, 
            //which is executed after flow collection completes
        }
        .collect { object -> send(processRequest(object))}