如何使用ktor ContentNegotiation为WebSocket客户端实现JSON封装

au9on6nz  于 5个月前  发布在  Go
关注(0)|答案(1)|浏览(100)

我正在我当前的android项目中研究ktor客户端,用于消费WebSocket流。
我的ktor客户端配置如下:

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

    }
}

字符串
我的WebSocket会话配置如下:-

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


val eventResponse = json.decodeFromString<WebSocketResponse>(incoming)中的json是一个与ktor客户端中配置的json示例不同的json示例,因为我已经声明它用于通过改造处理restful API调用
其声明如下:

@OptIn(ExperimentalSerializationApi::class)
val json = Json {
    ignoreUnknownKeys = true
    isLenient = true
    encodeDefaults = true
    coerceInputValues = false
    explicitNulls = false
}


如何使用我为内容协商配置的json示例?

0qx6xfy6

0qx6xfy61#

您不能从ContentNegotiation插件访问Json示例,但您可以使用预定义的Json对象配置插件,并将其用于WebSockets数据包封装。

@OptIn(ExperimentalSerializationApi::class)
val jsonInstance = Json {
    ignoreUnknownKeys = true
    isLenient = true
    encodeDefaults = true
    coerceInputValues = false
    explicitNulls = false
}

val client = HttpClient {
    install(ContentNegotiation) {
        json(jsonInstance)
    }
}

// ... 
// Usage of jsonInstance for WebSockets packet deserialization

字符串

相关问题