如何在 Ktor websockets 上发送 ping

Posted

技术标签:

【中文标题】如何在 Ktor websockets 上发送 ping【英文标题】:How to send pings on Ktor websockets 【发布时间】:2020-02-13 22:27:36 【问题描述】:

我尝试在 api 文档和示例中进行搜索,但没有任何示例演示如何发送 ping 和接收 ping。唯一的例子是如何连接到 websocket 并发送文本here。 我还看到了服务器端的聊天示例here,我也仔细遵循了这一点(即在 WebSocket 安装的服务器端配置中设置 ping 间隔)。

我开始监听双方是否有乒乓,但没有一方收到任何 ping 消息。

如您所见here,没有配置客户端进行 ping 的选项。

我对如何发送 ping 感到非常困惑。

这是我的服务器端:

embeddedServer(
    CIO,
    80
) 
    install(io.ktor.websocket.WebSockets) 
        pingPeriod = Duration.ofSeconds(20)
    

    routing 
        webSocket("/ws") 
            for (frame in incoming) 
                when (frame) 
                    is Frame.Pong -> 
                        println("ping's response recieved")
                    

                    is Frame.Ping -> 
                        // just temporary block
                        println("ping recieved")
                    

                    is Frame.Text -> 
                        println(frame.readText())
                    
                
            
        
    
.apply  start() 

这是我的客户端:

val client = HttpClient(CIO) 
    install(WebSockets)


client.ws(
    method = HttpMethod.Get,
    host = "127.0.0.1",
    port = 80,
    path = "/ws"
) 

    send(Frame.Text("Hello World!"))

    for (frame in incoming) 
        when (frame) 
            is Frame.Pong -> 
                println("ping's response received")
            

            is Frame.Ping -> 
                // just temporary block
                println("ping recieved from server")
            

            is Frame.Text -> 
                println(frame.readText())
            
        
    

结果:

Hello World!

即websocket已连接,文本可以传输,但遗憾的是不能使用ping/pong功能。

我还为 here pingerponger 找到了一些功能,但现在它说它是 api 的一部分,并随着 WebsocketSession 的启动而自动启动,我还尝试将 pinger 放在客户端但那没有t 发送 ping 到服务器。

上述代码的结果只是 Hello world 打印在服务器控制台中,从客户端发送,但没有 ping 接收到消息。

【问题讨论】:

【参考方案1】:

我在让 OkHttp 使用 ping/pong 时遇到问题,所以我提交了这个问题 https://github.com/ktorio/ktor/issues/1803,其中一位开发人员回答说“我唯一可以推荐你的是尝试 CIO。是否支持手动 Ping/Pong使用 RawWebSockets 进行处理。”

自己没试过,但你应该看看https://github.com/ktorio/ktor/blob/master/ktor-features/ktor-websockets/jvm/test/io/ktor/tests/websocket/RawWebSocketTest.kt

【讨论】:

没错,websockets 不是完全可定制的,只有文本框是我们目前能够通过默认实现接收的,我已经评论了这个问题,让我们看看有什么反应。如果我们可以从默认实现中继承一些功能来创建自定义实现,那可能会更好。重新创建实现会很麻烦,如果您有任何想法,请提出来。

以上是关于如何在 Ktor websockets 上发送 ping的主要内容,如果未能解决你的问题,请参考以下文章

Android设备上的ktor websocket安装错误

Ktor websockets 身份验证

如何保持 Kotlin Ktor websocket 处于打开状态

ktor websocket flow api是如何工作的?

如何确保清除 ktor websocket 客户端创建的所有 Kotlin 协程?

尝试在客户端接收数据时,Ktor-websocket 库不执行任何操作