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
sendfunction to send text content to the client.Use the
incomingandoutgoingproperties 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.Textis a text frame. For this frame type, you can read its content usingFrame.Text.readText().Frame.Binaryis a binary frame. For this type, you can read its content usingFrame.Binary.readBytes().Frame.Closeis a closing frame. You can callFrame.Close.readReason()to get a close reason for the current session.
Use the
closefunction 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:
onConnecthappens at the start of the block.onMessagehappens after successfully reading a message (for example, withincoming.receive()) or using suspended iteration withfor(frame in incoming).onClosehappens when theincomingchannel is closed. That would complete the suspended iteration, or throw aClosedReceiveChannelExceptionwhen trying to receive a message`.onErroris 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.