```private fun Routing.ws() { val sessions = C...
# ktor
u
Copy code
private fun Routing.ws() {
    val sessions = Collections.synchronizedList(ArrayList<WebSocketServerSession>())
    webSocket("/ws") {
        sessions += this
        launch { <--------------
            while (isActive) {
                delay(1.seconds)
                send(Frame.Text(text = "test"))
            }
        }

        ....

        close()
        sessions -= this
    }
}
This is how I emit a message to a client every second But, how do I emit a message to all clients every second? I cannot simply for loop all sessions; since that websocket handler lambda is per session, right?
a
You can launch a background job on the server startup, which will send frames to all WebSocket clients. Here is an example:
Copy code
val connections = ConcurrentLinkedQueue<DefaultWebSocketServerSession>()

val server = embeddedServer(Netty, port = 8080) {
    install(WebSockets)

    routing {
        webSocket("/ws") {
            connections.add(this)
            while (isActive) {
                send(Frame.Text("Hello client"))
                delay(1000)
            }
        }
    }
}

val scope = CoroutineScope(server.application.coroutineContext)
server.monitor.subscribe(ApplicationStarted) {
    scope.launch {
        while (isActive) {
            for (session in connections) {
                session.send(Frame.Text("Hello all"))
            }
            delay(1000)
        }
    }
}

server.start(wait = true)
u
works thanks, however I wonder
Copy code
fun Application.module() {
    installs..

    launch {
        while (true) {
            delay(1.seconds)
            counter.update { it + 1 }
        }
    }
}
is there any issue with this? avoids instantiating scope explicitly, seems more elegant nevermind the counter; I'm just pointing to the
launch
in module lambda scope; that should be tied to application lifecycle no?
a
I'm just pointing to the
launch
in module lambda scope; that should be tied to application lifecycle no?
Yes
👍 1