Ktor 2.0.3 Help

Client WebSockets

Ktor supports the WebSocket protocol and allows you to create applications that require real-time data transfer from and to the server. For example, WebSockets can be used to create a chat application.

The Ktor client allows you to handle a WebSocket session for exchanging messages with the server. To learn about WebSocket support in a Ktor server, see Server WebSockets.

Supported engines

The Ktor client supports WebSockets for the following engines:

  • CIO

  • OkHttp

  • Js

  • Darwin

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:

val client = HttpClient(CIO) { install(WebSockets) { // Configure WebSockets } }

Optionally, you can configure the plugin inside the install block by passing the required options using WebSockets.Config.

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.

Session configuration might look as follows:

  1. Use the send function to send text content to the server.

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

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

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

Example

The example below shows how to send a message to the echo WebSocket endpoint and how to receive a response:

fun main() { val client = HttpClient(CIO) { install(WebSockets) } 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() }

You can find the full example here: client-websockets.

Last modified: 28 June 2022