Как сериализовать фрейм.текст веб-сокета в Ktor с помощью kotlinx.serialization

#kotlin #ktor #kotlinx.serialization

#kotlin #ktor #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()
            }
        }

 

я хочу сериализовать frame.readText() , чтобы вернуть объект класса
я совершенно новичок в мире Ktor, и я не знаю, возможно ли это

Комментарии:

1. Не могли бы вы, пожалуйста, получше объяснить, что у вас есть в вашей text переменной? Это строка JSON? Или что-то еще? Если у вас есть строка JSON, вы можете использовать kotlinx.serialization

Ответ №1:

Вы можете использовать базовый kotlinx.serialization , который, возможно, уже настроен для согласования содержимого. Если вы этого не сделали, инструкции можно найти здесь. Для этого потребуется сделать ваш класс (я принял имя ObjectType ) сериализуемым @Serializable . Более подробно здесь о том, как сделать класс сериализуемым, а также о том, как кодировать / декодировать в формат JSON. Я включил фрагмент решения:

 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()
            }
        }
 

Обычно я бы использовал поток (требуется 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))}