Ktor client WebSocket plugin - provides WebSocket support for the Ktor HTTP client on multiple platforms including iOS x64
—
Ktor Client WebSockets provides multiple functions for establishing WebSocket connections with different usage patterns and security options.
Establishes a WebSocket connection and executes a block with the session, automatically closing the connection afterward:
suspend fun HttpClient.webSocket(
method: HttpMethod = HttpMethod.Get,
host: String? = null,
port: Int? = null,
path: String? = null,
request: HttpRequestBuilder.() -> Unit = {},
block: suspend DefaultClientWebSocketSession.() -> Unit
)
suspend fun HttpClient.webSocket(
request: HttpRequestBuilder.() -> Unit,
block: suspend DefaultClientWebSocketSession.() -> Unit
)
suspend fun HttpClient.webSocket(
urlString: String,
request: HttpRequestBuilder.() -> Unit = {},
block: suspend DefaultClientWebSocketSession.() -> Unit
)Usage:
client.webSocket(
method = HttpMethod.Get,
host = "echo.websocket.org",
port = 80,
path = "/"
) {
send("Hello WebSocket!")
val frame = incoming.receive()
println("Received: ${frame}")
}
// Connection automatically closed after block completionURL string variant:
client.webSocket("ws://echo.websocket.org/") {
send("Hello from URL!")
val response = incoming.receive()
println("Response: $response")
}Creates a WebSocket session that must be manually managed and closed:
suspend fun HttpClient.webSocketSession(
method: HttpMethod = HttpMethod.Get,
host: String? = null,
port: Int? = null,
path: String? = null,
block: HttpRequestBuilder.() -> Unit = {}
): DefaultClientWebSocketSession
suspend fun HttpClient.webSocketSession(
block: HttpRequestBuilder.() -> Unit
): DefaultClientWebSocketSession
suspend fun HttpClient.webSocketSession(
urlString: String,
block: HttpRequestBuilder.() -> Unit = {}
): DefaultClientWebSocketSessionUsage:
val session = client.webSocketSession(
host = "echo.websocket.org",
port = 80,
path = "/"
)
try {
session.send("Manual session message")
val frame = session.incoming.receive()
println("Received: $frame")
} finally {
session.close()
}Convenience alias for webSocket() with identical functionality:
suspend fun HttpClient.ws(
method: HttpMethod = HttpMethod.Get,
host: String? = null,
port: Int? = null,
path: String? = null,
request: HttpRequestBuilder.() -> Unit = {},
block: suspend DefaultClientWebSocketSession.() -> Unit
)
suspend fun HttpClient.ws(
request: HttpRequestBuilder.() -> Unit,
block: suspend DefaultClientWebSocketSession.() -> Unit
)
suspend fun HttpClient.ws(
urlString: String,
request: HttpRequestBuilder.() -> Unit = {},
block: suspend DefaultClientWebSocketSession.() -> Unit
)Usage:
client.ws("ws://echo.websocket.org/") {
send("Short alias message")
val frame = incoming.receive()
println("Response: $frame")
}Establishes secure WebSocket connections over TLS/SSL:
suspend fun HttpClient.wss(
method: HttpMethod = HttpMethod.Get,
host: String? = null,
port: Int? = null,
path: String? = null,
request: HttpRequestBuilder.() -> Unit = {},
block: suspend DefaultClientWebSocketSession.() -> Unit
)
suspend fun HttpClient.wss(
request: HttpRequestBuilder.() -> Unit,
block: suspend DefaultClientWebSocketSession.() -> Unit
)
suspend fun HttpClient.wss(
urlString: String,
request: HttpRequestBuilder.() -> Unit = {},
block: suspend DefaultClientWebSocketSession.() -> Unit
)Usage:
client.wss(
host = "secure.websocket.example.com",
port = 443,
path = "/secure-endpoint"
) {
send("Secure message")
val frame = incoming.receive()
println("Secure response: $frame")
}URL string variant:
client.wss("wss://secure.websocket.example.com/api/v1/socket") {
send("Secure connection established")
val response = incoming.receive()
println("Secure response: $response")
}All connection functions accept a request configuration block for customizing the WebSocket handshake:
client.webSocket("ws://example.com/") {
headers {
append("Authorization", "Bearer $token")
append("X-Custom-Header", "value")
}
}client.webSocket(
host = "api.example.com",
path = "/socket"
) {
url {
parameters.append("token", authToken)
parameters.append("room", roomId)
}
}client.webSocket("ws://example.com:8080/socket") {
url {
protocol = URLProtocol.WSS // Override to secure
port = 443 // Override port
}
}client.webSocket("ws://echo.websocket.org/") {
// Send text frame
send("Hello WebSocket!")
// Receive and process frames
for (frame in incoming) {
when (frame) {
is Frame.Text -> {
val text = frame.readText()
println("Received text: $text")
if (text == "exit") break
}
is Frame.Close -> {
println("Connection closed: ${frame.readReason()}")
break
}
else -> println("Received frame: $frame")
}
}
}client.webSocket("ws://example.com/binary") {
// Send binary frame
val data = "Binary data".toByteArray()
send(Frame.Binary(true, data))
// Receive binary frame
val frame = incoming.receive()
if (frame is Frame.Binary) {
val receivedData = frame.data
println("Received ${receivedData.size} bytes")
}
}client.webSocket("ws://secure.example.com/socket") {
headers {
append("Authorization", "Bearer $jwt")
append("X-API-Key", apiKey)
}
} {
send("Authenticated connection established")
for (frame in incoming) {
when (frame) {
is Frame.Text -> {
handleMessage(frame.readText())
}
is Frame.Close -> break
else -> { /* Handle other frame types */ }
}
}
}withTimeout(30.seconds) {
client.webSocket("ws://example.com/socket") {
timeout {
requestTimeoutMillis = 15_000
connectTimeoutMillis = 10_000
}
} {
// WebSocket operations
send("Message with timeout")
val response = incoming.receive()
println("Response: $response")
}
}WebSocket connections can fail during handshake or operation:
try {
client.webSocket("ws://unreliable.example.com/") {
send("Test message")
val frame = incoming.receive()
println("Success: $frame")
}
} catch (e: WebSocketException) {
println("WebSocket error: ${e.message}")
} catch (e: ConnectTimeoutException) {
println("Connection timeout: ${e.message}")
} catch (e: IOException) {
println("Network error: ${e.message}")
}Install with Tessl CLI
npx tessl i tessl/maven-io-ktor--ktor-client-websockets