I’ve found documentation for an insecure ktor websocket server (ws://…):
https://ktor.io/docs/creating-web-socket-chat.html#creating-the-chat-client
I’ve found documentation for a secure ktor http server (https://…)
https://github.com/ktorio/ktor-documentation/tree/main/codeSnippets/snippets/ssl-embedded-server
But I can’t seem to find or figure out how to serve a secure ktor websocket server (wss://…)
I’d rather not use an SSL reverse proxy like nginx in front of it.
EDIT: Here’s code:
import io.ktor.application.*
import io.ktor.http.cio.websocket.*
import io.ktor.network.tls.certificates.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.websocket.*
import java.io.*
fun main() {
val keyStoreFile = File("build/keystore.jks")
val keystore = generateCertificate(
file = keyStoreFile,
keyAlias = "sampleAlias",
keyPassword = "foobar",
jksPassword = "foobar"
)
val environment = applicationEngineEnvironment {
sslConnector(
keyStore = keystore,
keyAlias = "sampleAlias",
keyStorePassword = { "foobar".toCharArray() },
privateKeyPassword = { "foobar".toCharArray() }) {
port = 8443
keyStorePath = keyStoreFile
}
module(Application::module)
}
embeddedServer(Netty, environment).start(wait = true)
}
private fun Application.module() {
install(WebSockets)
routing {
get("/") { // works at https://localhost:8443 in Firefox after approving cert
call.respondText("This is https")
}
webSocket("/chat") { // fails at wss://localhost:8443/chat in Websocket js client with "Firefox can’t establish a connection to the server"
send("This is wss")
}
}
}
2
Answers
The problem was using a self-signed certificate. I tried Chrome and set it to accept a self-signed certificate on localhost, which works. The error message Firebox provided suggested that a connection could not be established, when in fact it rejected the certificate.
A secure websocket server using ktor does in fact work like @AleksiTierman suggested. It is configured the same way as an https server.
I’ve tested this with postman and works fine.
You can not use ws:// or wss:// protocols in browsers, use postman or other websocket clients instead.
Application.kt :
Sockets.kt :