Ktor client WebSockets plugin for Linux x64 platform - enables full-duplex communication between client and server over TCP connection
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Ktor Client WebSockets provides comprehensive WebSocket client capabilities for Kotlin applications running on Linux x64 platforms. As part of the Ktor framework, it enables full-duplex, real-time communication between clients and servers over a single TCP connection with native performance optimizations.
build.gradle.kts:dependencies {
implementation("io.ktor:ktor-client-websockets-linuxx64:3.2.0")
}import io.ktor.client.*
import io.ktor.client.plugins.websocket.*
import io.ktor.websocket.*For WebSocket frames:
import io.ktor.websocket.Frame
import io.ktor.websocket.FrameTypeimport io.ktor.client.*
import io.ktor.client.plugins.websocket.*
import io.ktor.websocket.*
import kotlin.time.Duration.Companion.seconds
// Install WebSocket plugin
val client = HttpClient {
install(WebSockets) {
pingInterval = 30.seconds
maxFrameSize = 1024 * 1024 // 1MB
}
}
// Connect and use WebSocket
client.webSocket("ws://echo.websocket.org") {
// Send text message
send("Hello WebSocket!")
// Receive messages
for (frame in incoming) {
when (frame) {
is Frame.Text -> println("Received: ${frame.readText()}")
is Frame.Binary -> println("Received binary: ${frame.data.size} bytes")
is Frame.Close -> break
}
}
}
client.close()Ktor WebSocket client is built around several key components:
WebSocket plugin installation and configuration with ping intervals, frame size limits, and extension support.
class WebSockets internal constructor(
val pingIntervalMillis: Long,
val maxFrameSize: Long,
val contentConverter: WebsocketContentConverter? = null
) : HttpClientPlugin<WebSockets.Config, WebSockets>
class Config {
var pingIntervalMillis: Long
var maxFrameSize: Long
var contentConverter: WebsocketContentConverter?
var pingInterval: Duration?
fun extensions(block: WebSocketExtensionsConfig.() -> Unit)
}
fun HttpClientConfig<*>.WebSockets(config: WebSockets.Config.() -> Unit)Core connection establishment functions for creating WebSocket sessions with various configuration options.
suspend fun HttpClient.webSocket(
request: HttpRequestBuilder.() -> Unit,
block: suspend DefaultClientWebSocketSession.() -> Unit
)
suspend fun HttpClient.webSocketSession(
block: HttpRequestBuilder.() -> Unit
): DefaultClientWebSocketSession
suspend fun HttpClient.ws(
host: String? = null,
port: Int? = null,
path: String? = null,
block: suspend DefaultClientWebSocketSession.() -> Unit
)
suspend fun HttpClient.wss(
host: String? = null,
port: Int? = null,
path: String? = null,
block: suspend DefaultClientWebSocketSession.() -> Unit
)WebSocket session interfaces providing frame-level control and connection lifecycle management.
interface ClientWebSocketSession : WebSocketSession {
val call: HttpClientCall
}
class DefaultClientWebSocketSession(
override val call: HttpClientCall,
delegate: DefaultWebSocketSession
) : ClientWebSocketSession, DefaultWebSocketSession
interface WebSocketSession : CoroutineScope {
var masking: Boolean
var maxFrameSize: Long
val incoming: ReceiveChannel<Frame>
val outgoing: SendChannel<Frame>
val extensions: List<WebSocketExtension<*>>
}Low-level WebSocket frame handling for text, binary, and control frame processing.
sealed class Frame {
val fin: Boolean
val frameType: FrameType
val data: ByteArray
val rsv1: Boolean
val rsv2: Boolean
val rsv3: Boolean
class Text(text: String) : Frame
class Binary(fin: Boolean, data: ByteArray) : Frame
class Close : Frame
class Ping(data: ByteArray) : Frame
class Pong(data: ByteArray) : Frame
}
enum class FrameType(val controlFrame: Boolean, val opcode: Int) {
TEXT, BINARY, CLOSE, PING, PONG
}
fun Frame.Text.readText(): String
fun Frame.readBytes(): ByteArray
fun Frame.Close.readReason(): CloseReason?Content converter integration for automatic serialization/deserialization of objects to/from WebSocket frames.
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
val DefaultClientWebSocketSession.converter: WebsocketContentConverter?interface WebsocketContentConverter {
suspend fun serialize(
charset: Charset,
typeInfo: TypeInfo,
value: Any?
): Frame
suspend fun deserialize(
charset: Charset,
typeInfo: TypeInfo,
content: Frame
): Any?
}
data object WebSocketCapability : HttpClientEngineCapability<Unit>
data object WebSocketExtensionsCapability : HttpClientEngineCapability<Unit>/** Constant indicating that WebSocket pinger is disabled */
const val PINGER_DISABLED: Long = 0class WebSocketException(message: String, cause: Throwable?) : IllegalStateException
class ProtocolViolationException(message: String) : Exception
class FrameTooBigException(message: String) : Exceptioninterface WebSocketExtension<ConfigType : Any> {
val protocols: List<WebSocketExtensionHeader>
fun clientNegotiation(extensions: List<WebSocketExtensionHeader>): Boolean
}
interface WebSocketExtensionFactory<ConfigType : Any, ExtensionType : WebSocketExtension<ConfigType>>
class WebSocketExtensionsConfig {
fun <Config : Any, Extension : WebSocketExtension<Config>> install(
extension: WebSocketExtensionFactory<Config, Extension>,
configure: Config.() -> Unit = {}
)
}
class WebSocketExtensionHeader(val name: String, val parameters: List<String>)
/** Parse WebSocket extension headers from HTTP header value */
fun parseWebSocketExtensions(value: String): List<WebSocketExtensionHeader>WebSocket operations can throw several types of exceptions: