WebSockets in Helidon SE

Santiago Pericas-Geertsen
Helidon
Published in
2 min readJun 25, 2020

Helidon integrates with Tyrus [1] to provide support for the Jakarta WebSocket API [2]. The WebSocket API enables Java applications to participate in WebSocket interactions as servers or clients.

Helidon SE support is based on the TyrusSupport class which is akin to JerseySupport, and enables Helidon applications to defined both annotated and programmatic WebSocket endpoints.

Project Dependencies

To use the WebSocket extension in your Helidon SE application, simply add the following dependency to your POM file:

WebSockets Dependency in SE

WebSocket Example

Let us explore an implementation of a simple application that uses a REST resource to push messages into a shared queue and a programmatic WebSocket endpoint to download messages from the queue, one at a time, over a connection. The example will show how REST and WebSocket connections can be seamlessly combined into a Helidon SE application.

Let us start by looking at MessageQueueService:

MessageQueueService Class

This class exposes a REST resource where messages can be posted. Upon receiving a message, it simply pushes it into a shared queue and returns 204 (no content). Note that the queue is implemented by the singleton class MessageQueue.

Messages pushed into the queue can be obtained by opening a WebSocket connection served by MessageBoardEndpoint:

MessageBoardEndpoint Class

This is a programmatic endpoint that extends classEndpoint. The method onOpen is invoked for every new connection. In this example, the application registers a message handler for strings, and when the special SEND message is received, it empties the shared queue sending messages over the WebSocket connection.

In Helidon SE, REST and WebSocket classes need to be manually registered into the web server. This is accomplished during the creation of theRouting instance as shown next:

Registering Endpoints

This code snippet uses multiple builders for Routing, TyrusSupport and ServerEndpointConfig. In particular, it registers MessageBoardEndpoint.class at /websocket and associates with it a message encoder. For more information on message encoders and decoders see [2]; in this example, UppercaseEncoder.class simply uppercases every message sent from the server.

Endpoint methods in Helidon SE are executed in Netty’s worker thread pool. Threads in this pool are intended to be non-blocking, thus it is recommended for any blocking or long-running operation triggered by an endpoint method to be executed using a separate thread pool. Helidon includes a configurable thread pool supplier for cases such as this, see io.helidon.common.configurable.ThreadPoolSupplier.

For more information about this example, the reader is referred to [3].

[1]https://projects.eclipse.org/projects/ee4j.tyrus
[2]https://projects.eclipse.org/projects/ee4j.websocket
[3]https://github.com/oracle/helidon/tree/master/examples/webserver/websocket

--

--