Ktor 2.3.10 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. For example, WebSockets can be used to create a chat application.

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) }

Configure WebSockets

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

  • Use the maxFrameSize property to set a maximum Frame that could be received or sent.

  • Use the contentConverter property to set a converter for serialization/deserialization.

val client = HttpClient(CIO) { install(WebSockets) { pingInterval = 20_000 } }
  • Use the pingPeriod property to specify the duration between pings.

The pingPeriod property is not applicable for the OkHttp engine. To set the ping interval for OkHttp, you can use the engine configuration:

import io.ktor.client.engine.okhttp.OkHttp val client = HttpClient(OkHttp) { engine { preconfigured = OkHttpClient.Builder() .pingInterval(20, TimeUnit.SECONDS) .build() } }

Handle a WebSockets session

API overview

A client's WebSocket session is represented by the DefaultClientWebSocketSession interface. This interface exposes the API that allows you to send/receive WebSocket frames and close a session. HttpClient allows you to get access to a WebSocket session in one of the following ways:

  • 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.

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

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

  • Use the incoming and outgoing properties to access the channels for receiving and sending WebSocket frames. A frame is represented by the Frame class.

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

When handling a session, you can check a frame type, for example:

  • Frame.Text is a text frame. For this frame type, you can read its content using Frame.Text.readText().

  • Frame.Binary is a binary frame. For this type, you can read its content using Frame.Binary.readBytes().

  • Frame.Close is a closing frame. You can call Frame.Close.readReason() to get a close reason for the current session.

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) { pingInterval = 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: 02 April 2024