Ktor 3.0.1 Help

WebSockets

WebSocket is a protocol which provides a full-duplex communication session between the user's browser and a server over a single TCP connection. It is particularly useful for creating applications that require real-time data transfer from and to the server.

Ktor supports the WebSocket protocol both on the server-, and the client-side.

The Websockets plugin for the client allows you to handle a WebSocket session for exchanging messages with a server.

Add dependencies

To use WebSockets, you need to include the ktor-client-websockets artifact in the build script:

implementation("io.ktor:ktor-client-websockets:$ktor_version")
implementation "io.ktor:ktor-client-websockets:$ktor_version"
<dependency> <groupId>io.ktor</groupId> <artifactId>ktor-client-websockets-jvm</artifactId> <version>${ktor_version}</version> </dependency>

You can learn more about artifacts required by the Ktor client from Adding client dependencies.

Install WebSockets

To install the WebSockets plugin, pass it to the install function inside a client configuration block:

import io.ktor.client.* import io.ktor.client.engine.cio.* import io.ktor.client.plugins.websocket.* //... val client = HttpClient(CIO) { install(WebSockets) }

Configuration

Optionally, you can configure the plugin inside the install block by passing the supported properties of the WebSockets.Config.

maxFrameSize

Set a maximum Frame size that could be received or sent.

contentConverter

Set a converter for serialization/deserialization.

pingIntervalMillis

Specify the duration between pings in a Long format.

pingInterval

Specify the duration between pings in a Duration format.

In the following example, the WebSockets plugin is configured with a ping interval of 20 seconds (20_000 milliseconds) to automatically send ping frames and keep the WebSocket connection alive:

val client = HttpClient(CIO) { install(WebSockets) { pingIntervalMillis = 20_000 } }

Working with WebSocket sessions

A client's WebSocket session is represented by the DefaultClientWebSocketSession interface. This interface exposes the API that allows you to send and receive WebSocket frames, and close a session.

Access a WebSocket session

HttpClient provides two primary ways to access a WebSocket session:

  • The webSocket() function accepts DefaultClientWebSocketSession as a block argument.

    runBlocking { client.webSocket( method = HttpMethod.Get, host = "127.0.0.1", port = 8080, path = "/echo" ) { // this: DefaultClientWebSocketSession } }
  • The webSocketSession() function returns the DefaultClientWebSocketSession instance and allows you to access a session outside the runBlocking or launch scope.

Handle WebSocket sessions

Within the function block, you define the handler for the specified path. The following functions and properties are available within the block:

send()

Use the send() function to send text content to the server.

outgoing

Use the outgoing property to access the channels for sending WebSocket frames. A frame is represented by the Frame class.

incoming

Use the incoming property to access the channels for receiving WebSocket frames. A frame is represented by the Frame class.

close()

Use the close() function to send a close frame with the specified reason.

Frame types

You can inspect the type of WebSocket frame and handle it accordingly. Some common frame types are:

  • Frame.Text represents a text frame. Use Frame.Text.readText() to read its content.

  • Frame.Binary represents a binary frame. Use Frame.Binary.readBytes() to read its content.

  • Frame.Close represents a closing frame. Use Frame.Close.readReason() to get the reason for the session's closure.

Example

The example below creates the echo WebSocket endpoint and shows how to send and receive a message to and from a server.

fun main() { val client = HttpClient(CIO) { install(WebSockets) { pingIntervalMillis = 20_000 } } runBlocking { client.webSocket(method = HttpMethod.Get, host = "127.0.0.1", port = 8080, path = "/echo") { while(true) { val othersMessage = incoming.receive() as? Frame.Text println(othersMessage?.readText()) val myMessage = Scanner(System.`in`).next() if(myMessage != null) { send(myMessage) } } } } client.close() }

For the full example, see client-websockets.

Last modified: 10 October 2024