Reputation: 13443
Created a ktor server websocket endpoint.
It refuses to stay open, despite being in a while (true)
loop:
Server
routing {
webSocket("/data") {
while (true) {
send(Frame.Text("Howdy"))
delay(5000)
}
}
}
Client (Browser)
const ws = new WebSocket("ws://www.example.com:1234/data")
Client (browser) connects, and receives the message, but then the socket closes.
Why does this ws keep closing? I never issued a "close" command. How can I keep it open, so that new queued messages can be sent?
Reference: https://ktor.io/docs/servers-features-websockets.html#usage
Upvotes: 3
Views: 5043
Reputation: 7671
My guess is you are not registering listeners on the client websocket and once the connection is established it disconnects due to no listeners. Or maybe the messages are being received, but you need to output them somewhere by registering an explicit listener.
In order to test your code I tried this Ktor WebSocket Chat tutorial. I started by cloning the sample repository and opening the server folder with IntelliJ IDEA CE. Then, I opened the Application.kt
file and replaced the Application module with the following lines, closely resembling your example:
@Suppress("unused")
fun Application.module() {
install(WebSockets)
routing {
webSocket("/data") {
send("You are connected!")
while (true) {
send(Frame.Text("Howdy"))
delay(1_000)
}
}
}
}
That tutorial tells you in chapter 3 to open an html echo websocket client, but that did not work for me, it would always say ERROR: undefined
(I guess due to paranoid network permissions?). However, at the bottom of that webpage, there's an example HTML code to connect to the websocket, and it worked! I copied the example and modified it a bit, put the following lines into a test.html
file:
<!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>
Once you have the ktor websocket server running opening that HTML file shows the following lines for me, which shows that the connection is established, as the server is pumping periodically Howdy
messages until the HTML javascript timeout triggers and closes the socket:
CONNECTED
SENT: WebSocket rocks
RESPONSE: Howdy
RESPONSE: Howdy
RESPONSE: Howdy
RESPONSE: Howdy
RESPONSE: Howdy
DISCONNECTED
EDIT UPDATE: to test if the socket is not receiving messages or it is receiving them and not printing them, I further modified testWebSocket()
in my test.html
file to contain the following lines:
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) };
}
With these lines, which are equivalent to your original code, I don't get any answer. But if I open the Safari network debug panel and click on the data stream, I can see how the HTML page is still receiving the Howdy
events before the timeout closes the socket explicitly.
Upvotes: 5