I am investigating ktor client in my current android project for consuming a websocket stream.
my ktor client is configured as follows:-
val client = HttpClient(OkHttp) {
install(Logging) {
logger = Logger.DEFAULT
level = LogLevel.ALL
}
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = false
isLenient = true
encodeDefaults = true
coerceInputValues = true
explicitNulls = false
})
}
install(WebSockets) {
pingInterval = 20_000
}
}
with my websocket session configured as shown below:-
client.webSocket(urlString = "wss://stream.org") {
incoming.consumeEach { frame ->
when (frame) {
is Frame.Binary -> println("Frame.Binary = $frame")
is Frame.Text -> {
println("Frame.Text = $frame")
val incoming = frame.readText()
println("\tincoming $incoming")
val eventResponse = json.decodeFromString<WebSocketResponse>(incoming)
when (eventResponse.event) {
Event.CONNECTED -> println("Event.SUBSCRIPTION_CREATED = $incoming")
Event.SUBSCRIPTION_CREATED -> println("Event.SUBSCRIPTION_CREATED = $incoming")
Event.SUBSCRIPTION_DELETED -> println("Event.SUBSCRIPTION_DELETED = $incoming")
Event.TOPIC_ADDED -> println("Event.TOPIC_ADDED = $incoming")
Event.TOPIC_REMOVED -> println("Event.TOPIC_REMOVED = $incoming")
Event.TOPIC_UPDATED -> println("Event.TOPIC_UPDATED = $incoming")
else -> TODO("Unexpected event $eventResponse")
}
}
is Frame.Close -> println("Frame.Close = $frame")
is Frame.Ping -> println("Frame.Ping = $frame")
is Frame.Pong -> println("Frame.Pong = $frame")
else -> TODO("Unexpected frame = $frame")
}
}
}
the json in val eventResponse = json.decodeFromString<WebSocketResponse>(incoming)
is a different json instance than the one configured in the ktor client, as i have it already declared for processing restful api calls via retrofit
its declared as follows:-
@OptIn(ExperimentalSerializationApi::class)
val json = Json {
ignoreUnknownKeys = true
isLenient = true
encodeDefaults = true
coerceInputValues = false
explicitNulls = false
}
how do i use the json instance i configured for content negotiation?
You cannot access the
Jsoninstance from theContentNegotiationplugin, but you can configure the plugin with the predefinedJsonobject and use it for the WebSockets packet deserialization too.