【问题标题】:How to keep a Kotlin Ktor websocket open如何保持 Kotlin Ktor websocket 处于打开状态
【发布时间】:2021-03-26 14:34:51
【问题描述】:

创建了一个 ktor 服务器 websocket 端点。

尽管处于while (true) 循环中,但它拒绝保持打开状态:

服务器

routing {
    webSocket("/data") {
        while (true) {
            send(Frame.Text("Howdy"))
            delay(5000)
        }
    }
}

客户端(浏览器)

const ws = new WebSocket("ws://www.example.com:1234/data")

客户端(浏览器)连接并接收消息,但随后套接字关闭。

为什么这个 ws 一直关闭?我从未发出过“关闭”命令。如何保持打开状态,以便发送新的排队消息?

参考: https://ktor.io/docs/servers-features-websockets.html#usage

【问题讨论】:

    标签: kotlin websocket ktor


    【解决方案1】:

    我的猜测是您没有在客户端 websocket 上注册侦听器,一旦建立连接,由于没有侦听器而断开连接。或者可能正在接收消息,但您需要通过注册显式侦听器将它们输出到某个地方。

    为了测试您的代码,我尝试了this Ktor WebSocket Chat tutorial。我首先克隆 the sample repository 并使用 IntelliJ IDEA CE 打开服务器文件夹。然后,我打开了Application.kt 文件并用以下几行替换了 Application 模块,与您的示例非常相似:

    @Suppress("unused")
    fun Application.module() {
        install(WebSockets)
        routing {
            webSocket("/data") {
                send("You are connected!")
                while (true) {
                    send(Frame.Text("Howdy"))
                    delay(1_000)
                }
            }
        }
    }
    

    那个教程在第 3 章告诉你打开an html echo websocket client,但这对我不起作用,它总是说ERROR: undefined(我猜是因为偏执的网络权限?)。但是,在该网页的底部,有一个连接到 websocket 的示例 HTML 代码,它工作正常!我复制了示例并稍作修改,将以下行放入test.html 文件中:

      <!DOCTYPE html>
      <meta charset="utf-8" />
      <title>WebSocket Test</title>
      <script language="javascript" type="text/javascript">
    
      var wsUri = "ws://localhost:8080/data";
      var output;
    
      function init()
      {
        output = document.getElementById("output");
        testWebSocket();
        window.setTimeout(delayedTest, 5000);
      }
    
      function delayedTest()
      {
        websocket.close();
        //alert("delayed");
      }
    
      function testWebSocket()
      {
        websocket = new WebSocket(wsUri);
        websocket.onopen = function(evt) { onOpen(evt) };
        websocket.onclose = function(evt) { onClose(evt) };
        websocket.onmessage = function(evt) { onMessage(evt) };
        websocket.onerror = function(evt) { onError(evt) };
      }
    
      function onOpen(evt)
      {
        writeToScreen("CONNECTED");
        doSend("WebSocket rocks");
      }
    
      function onClose(evt)
      {
        writeToScreen("DISCONNECTED");
      }
    
      function onMessage(evt)
      {
        writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
        //websocket.close();
      }
    
      function onError(evt)
      {
        writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
      }
    
      function doSend(message)
      {
        writeToScreen("SENT: " + message);
        websocket.send(message);
      }
    
      function writeToScreen(message)
      {
        var pre = document.createElement("p");
        pre.style.wordWrap = "break-word";
        pre.innerHTML = message;
        output.appendChild(pre);
      }
    
      window.addEventListener("load", init, false);
    
      </script>
    
      <h2>WebSocket Test</h2>
    
      <div id="output"></div>
    

    一旦您运行了 ktor websocket 服务器,打开该 HTML 文件就会向我显示以下行,这表明连接已建立,因为服务器会定期发送 Howdy 消息,直到 HTML javascript 超时触发并关闭套接字:

    CONNECTED
    
    SENT: WebSocket rocks
    
    RESPONSE: Howdy
    
    RESPONSE: Howdy
    
    RESPONSE: Howdy
    
    RESPONSE: Howdy
    
    RESPONSE: Howdy
    
    DISCONNECTED
    

    编辑更新:为了测试套接字是否没有接收消息,或者它正在接收消息但没有打印它们,我在我的test.html 文件中进一步修改了testWebSocket() 以包含以下行:

      function testWebSocket()
      {
        websocket = new WebSocket(wsUri);
        //websocket.onopen = function(evt) { onOpen(evt) };
        //websocket.onclose = function(evt) { onClose(evt) };
        //websocket.onmessage = function(evt) { onMessage(evt) };
        //websocket.onerror = function(evt) { onError(evt) };
      }
    

    这些行相当于您的原始代码,我没有得到任何答案。但是,如果我打开 Safari 网络调试面板并单击 data 流,我可以看到在超时显式关闭套接字之前 HTML 页面仍然接收Howdy 事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-17
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 2017-05-03
      • 2013-07-01
      • 2011-05-10
      相关资源
      最近更新 更多