I've been delving into Ktor to learn about Websockets, but despite spending numerous hours researching similar questions, I'm still unable to pinpoint the root of my issue. I'm trying to open multiple websocket sessions using Ktor to be able to send and receive messages between the users. However, once I create a websocket session, it closes itself. I'm initializing the websocket session once the main login page of my application opens up.
I've also tried understanding the answer to this same problem, but they're using a html file. Is there another solution to this problem?
Here is the code where I create the websocket session:
// In CommManager object
suspend fun receiveMessage(session: DefaultWebSocketSession) {
var text = ""
while (connected.get() == true) {
try {
for (othersMessages in session.incoming) {
othersMessages as? Frame.Text ?: continue
text = othersMessages.readText()
println(text)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
// In the login page
suspend fun createWebsocketSession() {
val session = client.webSocketSession(method = HttpMethod.Get, host = "hosturl", port = 8080, path = "/webSocketSession")
CommManager.connected.set(true)
CommManager.receiveMessage(session)
}
init
{
// Initialize Websocket session here
coroutine.launch()
{
createWebsocketSession()
}
}
As for the server side:
routing()
{
webSocket("/webSocketSession") {
ConnectionsHandler.connectWebSocketSession(this)
}
}
// ConnectionsHandler object
fun connectWebSocketSession(session: DefaultWebSocketSession){
println("adding new user")
val thisConnection = Connection(session)
webSocketUserList += thisConnection
println("${thisConnection.name} is connected!")
}
After running the server and then the client, this is what I get as output from the server:
Route resolve result:
SUCCESS @ /webSocketSession/(method:GET)/(header:Connection = Upgrade)/(header:Upgrade = websocket)
2024-03-19 09:35:25.142 [eventLoopGroupProxy-4-1] TRACE i.k.s.p.c.ContentNegotiation - Skipping because body is already converted.
2024-03-19 09:35:25.165 [eventLoopGroupProxy-3-5] TRACE io.ktor.websocket.WebSocket - Starting default WebSocketSession(io.ktor.websocket.DefaultWebSocketSessionImpl@49a741b5) with negotiated extensions:
2024-03-19 09:35:25.169 [eventLoopGroupProxy-3-5] TRACE io.ktor.server.websocket.WebSockets - Starting websocket session for /webSocketSession
adding new user
user0 is connected!
2024-03-19 09:35:25.218 [eventLoopGroupProxy-3-5] TRACE io.ktor.websocket.WebSocket - Sending Frame CLOSE (fin=true, buffer len = 2) from session io.ktor.websocket.DefaultWebSocketSessionImpl@49a741b5
2024-03-19 09:35:25.222 [eventLoopGroupProxy-3-5] TRACE io.ktor.websocket.WebSocket - Sending Close Sequence for session io.ktor.websocket.DefaultWebSocketSessionImpl@49a741b5 with reason CloseReason(reason=NORMAL, message=) and exception null
2024-03-19 09:35:25.251 [eventLoopGroupProxy-3-3] TRACE io.ktor.websocket.WebSocket - WebSocketSession(StandaloneCoroutine{Active}@2cea43ee) receiving frame Frame CLOSE (fin=true, buffer len = 2)
From my understanding, "sending Frame CLOSE" means that it is closing the websocket session, but I haven't specified any command to do so in the client or the server. Am I missing something in the server side to keep the session running? If you need more information about the problem, please tell me and I'll edit the post.
The WebSocket session is closed as soon as the last statement in the WebSocket handler is executed. To keep the session running, you can keep receiving the messages from the other end:
Also, you can use a
whileloop to prevent the session from closing: