Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 466
Abd al-Rahman Avatar asked Oct 27 '25 04:10

Abd al-Rahman


1 Answers

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))}
like image 142
Horațiu Udrea Avatar answered Oct 30 '25 10:10

Horațiu Udrea



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!