Server 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.
Ktor allows you to:
Configure basic WebSocket settings, such as frame size, a ping period, and so on.
Handle a WebSocket session for exchanging messages between the server and client.
Add WebSocket extensions. For example, you can use the Deflate extension or implement a custom extension.
Add dependencies
To enable WebSockets
support, you need to include the ktor-websockets
artifact in the build script:
Install WebSockets
To install the WebSockets
plugin, pass it to the install
function in the application initialization code. Depending on the way used to create a server, this can be the embeddedServer
function call ...
... or a specified module.
Configure WebSockets settings
Optionally, you can configure the plugin by passing WebSocketOptions to the install
function:
Handle WebSockets sessions
API overview
After you installed and configured the WebSockets
plugin, you are ready to handle a WebSocket session. First, you need to define a WebSocket endpoint on a server by calling the webSocket function inside the routing block:
For such an endpoint, a server accepts WebSocket requests to ws://localhost:8080/echo
when a default configuration is used.
Inside the webSocket
block, you need to handle a WebSocket session, which is represented by the DefaultWebSocketServerSession class. Session configuration might look as follows:
Use the
send
function to send text content to the client.Use the
incoming
andoutgoing
properties to access the channels for receiving and sending WebSocket frames. A frame is represented by the Frame class.When handing 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 usingFrame.Text.readText()
.Frame.Binary
is a binary frame. For this type, you can read its content usingFrame.Binary.readBytes()
.Frame.Close
is a closing frame. You can callFrame.Close.readReason()
to get a close reason for the current session.
Use the
close
function to send a close frame with the specified reason.
Below we'll take a look at the examples of using this API.
Example: Handle a single session
The example below shows how to create the echo
WebSocket endpoint to handle a session with one client:
You can find the full example here: server-websockets.
Example: Handle multiple sessions
To handle multiple WebSocket sessions (for example, for a chat application), you need to store each session on a server. For example, you can define a connection with a unique name and associate it with a specified session. A sample Connection
class below shows how to do this:
Then, you can create a new connection inside the webSocket
handler when a new client connects to the WebSocket endpoint:
You can find the full example here: server-websockets.
Testing
You can test WebSocket conversations by using the handleWebSocketConversation
function inside the withTestApplication
block:
The WebSocket API and Ktor
The standard events from the WebSocket API map to Ktor in the following way:
onConnect
happens at the start of the block.onMessage
happens after successfully reading a message (for example, withincoming.receive()
) or using suspended iteration withfor(frame in incoming)
.onClose
happens when theincoming
channel is closed. That would complete the suspended iteration, or throw aClosedReceiveChannelException
when trying to receive a message`.onError
is equivalent to other exceptions.
In both onClose
and onError
, the closeReason property is set.
In this sample, the infinite loop is only exited with an exception is risen: either a ClosedReceiveChannelException
or another exception.