or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/gradle-io-ktor--ktor-client-websockets-mingwx64

WebSocket client support for Ktor targeting the MinGW x64 platform, enabling native Windows applications built with Kotlin/Native to establish WebSocket connections.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes

pkg:gradle/io.ktor/ktor-client-websockets-mingwx64@3.2.x

To install, run

npx @tessl/cli install tessl/gradle-io-ktor--ktor-client-websockets-mingwx64@3.2.0

index.mddocs/

Ktor Client WebSockets (mingwx64)

Ktor WebSocket client plugin for MinGW x64 platform, enabling native Windows applications built with Kotlin/Native to establish WebSocket connections. This plugin provides complete WebSocket client functionality including bidirectional communication, message serialization, connection lifecycle management, and ping/pong support for connection health monitoring.

Package Information

  • Package Name: ktor-client-websockets-mingwx64
  • Package Type: gradle
  • Language: Kotlin
  • Target Platform: mingwx64 (Native Windows)
  • Installation: implementation("io.ktor:ktor-client-websockets-mingwx64:3.2.0")

Core Imports

import io.ktor.client.*
import io.ktor.client.plugins.websocket.*

For WebSocket frames and session types:

import io.ktor.websocket.*

For serialization support:

import io.ktor.websocket.serialization.*

Basic Usage

import io.ktor.client.*
import io.ktor.client.engine.winhttp.*
import io.ktor.client.plugins.websocket.*
import io.ktor.websocket.*

// Create client with WebSocket plugin
val client = HttpClient(WinHttp) {
    install(WebSockets) {
        pingInterval = 30.seconds
        maxFrameSize = 1024 * 1024 // 1MB
    }
}

// Connect and use WebSocket
client.webSocket(
    method = HttpMethod.Get,
    host = "echo.websocket.org",
    port = 80,
    path = "/"
) {
    // Send text message
    send(Frame.Text("Hello WebSocket!"))
    
    // Receive message
    for (frame in incoming) {
        when (frame) {
            is Frame.Text -> {
                val message = frame.readText()
                println("Received: $message")
            }
            is Frame.Binary -> {
                val data = frame.readBytes()
                println("Received binary data: ${data.size} bytes")
            }
            is Frame.Close -> {
                println("Connection closed")
                break
            }
            else -> {}
        }
    }
}

client.close()

Architecture

The Ktor WebSocket client plugin integrates with the Ktor HTTP client framework through several key components:

  • WebSockets Plugin: Core plugin that handles WebSocket upgrade negotiations and session management
  • ClientWebSocketSession: Client-specific session interface providing access to the underlying HTTP call
  • DefaultClientWebSocketSession: Default session implementation with ping/pong support and content serialization
  • Connection Builders: Extension functions for establishing WebSocket connections with various configuration options
  • Content Serialization: Optional converter for automatic serialization/deserialization of custom types
  • Extensions Support: Mechanism for WebSocket protocol extensions (deflate compression, etc.)

Capabilities

Plugin Installation and Configuration

Install and configure the WebSocket plugin for your HttpClient instance.

fun HttpClientConfig<*>.WebSockets(config: WebSockets.Config.() -> Unit)

class WebSockets {
    constructor()
    constructor(pingIntervalMillis: Long, maxFrameSize: Long)
    constructor(
        pingIntervalMillis: Long,
        maxFrameSize: Long,
        extensionsConfig: WebSocketExtensionsConfig,
        contentConverter: WebsocketContentConverter? = null
    )
    
    val pingIntervalMillis: Long
    val maxFrameSize: Long
    val contentConverter: WebsocketContentConverter?
}

fun WebSockets(
    pingInterval: Duration?,
    maxFrameSize: Long = Int.MAX_VALUE.toLong()
): WebSockets

class WebSockets.Config {
    var pingIntervalMillis: Long
    var maxFrameSize: Long
    var pingInterval: Duration?
    var contentConverter: WebsocketContentConverter?
    
    fun extensions(block: WebSocketExtensionsConfig.() -> Unit)
}

WebSocket Connection Establishment

Create WebSocket connections using various methods - session-based for manual management or block-based for automatic cleanup.

suspend fun HttpClient.webSocketSession(
    block: HttpRequestBuilder.() -> Unit
): DefaultClientWebSocketSession

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(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): DefaultClientWebSocketSession

suspend fun HttpClient.webSocket(
    request: HttpRequestBuilder.() -> Unit,
    block: suspend DefaultClientWebSocketSession.() -> Unit
)

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(
    urlString: String,
    request: HttpRequestBuilder.() -> Unit = {},
    block: suspend DefaultClientWebSocketSession.() -> Unit
)

Secure WebSocket Connections

Establish secure WebSocket connections over SSL/TLS using the WSS protocol.

suspend fun HttpClient.wss(
    request: HttpRequestBuilder.() -> Unit,
    block: suspend DefaultClientWebSocketSession.() -> Unit
)

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(
    urlString: String,
    request: HttpRequestBuilder.() -> Unit = {},
    block: suspend DefaultClientWebSocketSession.() -> Unit
)

Convenience Connection Functions

Shorthand functions for WebSocket connections - ws aliases for standard connections.

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
)

Session Management

Client-specific WebSocket session interfaces providing access to the underlying HTTP call and session management.

interface ClientWebSocketSession : WebSocketSession {
    val call: HttpClientCall
}

open class DefaultClientWebSocketSession(
    override val call: HttpClientCall,
    delegate: DefaultWebSocketSession
) : ClientWebSocketSession, DefaultWebSocketSession

val DefaultClientWebSocketSession.converter: WebsocketContentConverter?

Message Serialization

Automatic serialization and deserialization of custom types using configured content converters.

suspend fun DefaultClientWebSocketSession.sendSerialized(
    data: Any?,
    typeInfo: TypeInfo
)

suspend inline fun <reified T> DefaultClientWebSocketSession.sendSerialized(
    data: T
)

suspend fun <T> DefaultClientWebSocketSession.receiveDeserialized(
    typeInfo: TypeInfo
): T

suspend inline fun <reified T> DefaultClientWebSocketSession.receiveDeserialized(): T

interface WebsocketContentConverter {
    suspend fun serialize(
        charset: Charset,
        typeInfo: TypeInfo,
        value: Any?
    ): Frame
    
    suspend fun deserialize(
        charset: Charset,
        typeInfo: TypeInfo,
        content: Frame
    ): Any?
    
    fun isApplicable(frame: Frame): Boolean
}

suspend inline fun <reified T> WebsocketContentConverter.serialize(
    value: T,
    charset: Charset = Charsets.UTF_8
): Frame

suspend inline fun <reified T> WebsocketContentConverter.deserialize(
    content: Frame,
    charset: Charset = Charsets.UTF_8
): T

Engine Capabilities

Capability indicators for WebSocket support in HTTP client engines.

object WebSocketCapability : HttpClientEngineCapability<Unit>

object WebSocketExtensionsCapability : HttpClientEngineCapability<Unit>

Exception Handling

WebSocket-specific exception types for error handling.

class WebSocketException(message: String, cause: Throwable?) : IllegalStateException {
    constructor(message: String)
}

open class WebsocketContentConvertException(
    message: String,
    cause: Throwable? = null
) : ContentConvertException

class WebsocketConverterNotFoundException(
    message: String,
    cause: Throwable? = null
) : WebsocketContentConvertException

class WebsocketDeserializeException(
    message: String,
    cause: Throwable? = null,
    val frame: Frame
) : WebsocketContentConvertException

Constants

Important constants used in WebSocket configuration.

const val PINGER_DISABLED: Long = 0

Core WebSocket Types

WebSocket Session Interface

Base WebSocket session interface from the shared websocket module.

interface WebSocketSession : CoroutineScope {
    var masking: Boolean
    var maxFrameSize: Long
    val incoming: ReceiveChannel<Frame>
    val outgoing: SendChannel<Frame>
    val extensions: List<WebSocketExtension<*>>
    
    suspend fun send(frame: Frame)
    suspend fun flush()
}

class DefaultWebSocketSession : WebSocketSession

WebSocket Frames

Frame types for different kinds of WebSocket messages.

sealed class Frame {
    class Text(val data: ByteArray) : Frame {
        constructor(text: String)
        fun readText(): String
    }
    
    class Binary(val data: ByteArray) : Frame {
        fun readBytes(): ByteArray
    }
    
    class Close(val data: ByteArray) : Frame {
        constructor(reason: CloseReason?)
        fun readReason(): CloseReason?
    }
    
    class Ping(val data: ByteArray) : Frame {
        constructor()
    }
    
    class Pong(val data: ByteArray) : Frame {
        constructor()
    }
}

data class CloseReason(val code: Short, val message: String)

WebSocket Extensions

Extension mechanism for WebSocket protocol extensions.

interface WebSocketExtension<ConfigType : Any> {
    val factory: WebSocketExtensionFactory<ConfigType, out WebSocketExtension<ConfigType>>
    val protocols: List<WebSocketExtensionHeader>
    
    fun clientNegotiation(negotiatedProtocols: List<WebSocketExtensionHeader>): Boolean
    fun serverNegotiation(requestedProtocols: List<WebSocketExtensionHeader>): List<WebSocketExtensionHeader>
    fun processOutgoingFrame(frame: Frame): Frame
    fun processIncomingFrame(frame: Frame): Frame
}

interface WebSocketExtensionFactory<ConfigType : Any, ExtensionType : WebSocketExtension<ConfigType>> {
    val key: AttributeKey<ExtensionType>
    val rsv1: Boolean
    val rsv2: Boolean
    val rsv3: Boolean
    
    fun install(config: ConfigType.() -> Unit): ExtensionType
}

class WebSocketExtensionsConfig {
    fun <ConfigType : Any> install(
        extension: WebSocketExtensionFactory<ConfigType, *>,
        config: ConfigType.() -> Unit = {}
    )
    
    fun build(): List<WebSocketExtension<*>>
}

Usage Examples

Basic Text Messaging

client.webSocket("wss://echo.websocket.org") {
    // Send text message
    send(Frame.Text("Hello WebSocket!"))
    
    // Read response
    val response = incoming.receive()
    if (response is Frame.Text) {
        println("Echo: ${response.readText()}")
    }
}

Binary Data Transfer

client.webSocket(host = "example.com", port = 8080, path = "/websocket") {
    // Send binary data
    val binaryData = byteArrayOf(1, 2, 3, 4, 5)
    send(Frame.Binary(binaryData))
    
    // Receive binary response
    for (frame in incoming) {
        when (frame) {
            is Frame.Binary -> {
                val receivedData = frame.readBytes()
                println("Received ${receivedData.size} bytes")
            }
            is Frame.Close -> break
            else -> {}
        }
    }
}

Connection with Ping/Pong

val client = HttpClient(WinHttp) {
    install(WebSockets) {
        pingInterval = 30.seconds // Send ping every 30 seconds
        maxFrameSize = 1024 * 1024 // 1MB max frame size
    }
}

client.webSocket("wss://example.com/websocket") {
    // Ping frames are sent automatically
    // Connection will be kept alive with ping/pong
    
    for (frame in incoming) {
        when (frame) {
            is Frame.Text -> {
                println("Message: ${frame.readText()}")
            }
            is Frame.Ping -> {
                // Pong is sent automatically
                println("Ping received")
            }
            is Frame.Pong -> {
                println("Pong received")
            }
            is Frame.Close -> {
                println("Connection closed: ${frame.readReason()}")
                break
            }
            else -> {}
        }
    }
}

Serialized Object Communication

// Configure serialization
val client = HttpClient(WinHttp) {
    install(WebSockets) {
        contentConverter = KotlinxWebsocketSerializationConverter(Json)
    }
}

client.webSocket("wss://api.example.com/websocket") {
    // Send serialized object
    sendSerialized(UserMessage("Hello", "user123"))
    
    // Receive and deserialize
    val response = receiveDeserialized<ServerResponse>()
    println("Received: ${response.message}")
}

Connection Error Handling

try {
    client.webSocket("wss://unreachable.example.com") {
        send(Frame.Text("Hello"))
    }
} catch (e: WebSocketException) {
    println("WebSocket error: ${e.message}")
} catch (e: ConnectTimeoutException) {
    println("Connection timeout")
} catch (e: Exception) {
    println("General error: ${e.message}")
}