Backend Development 6 min read

Master Java 11 HttpClient WebSocket: Build, Listen, and Send Messages

This guide demonstrates how to use Java 11’s HttpClient to build a WebSocket client, implement a listener for various message events, and send both text and binary data, including a complete runnable example that showcases connection setup, message handling, and periodic sending.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
Master Java 11 HttpClient WebSocket: Build, Listen, and Send Messages

Continuing from the previous post, 10 examples mastering Java 11 HttpClient. Java 11 HttpClient can send http/https and also supports WebSocket, and is concise and easy to use.

1. Construct WebSocket Builder

Creating a WebSocket is straightforward; use

HttpClient.newHttpClient().newWebSocketBuilder()

to obtain a builder.

<code>// Build a WebSocket Builder
WebSocket.Builder webSocketBuilder = HttpClient.newHttpClient()
    .newWebSocketBuilder();

// Support subprotocols (implementation required)
webSocketBuilder.subprotocols("mqtt");

// Timeout configuration, e.g., 3 seconds
webSocketBuilder.connectTimeout(Duration.ofSeconds(3));

// Asynchronously build the WebSocket request
CompletableFuture<WebSocket> future = webSocketBuilder.buildAsync(uri, listener);
</code>

2. WebSocket Listener

WebSocket message listening is simple; implement

WebSocket.Listener

and optionally override methods such as

onOpen

,

onBinary

,

onPing

,

onPong

,

onClose

,

onError

, and

onText

. For large packets you can split them, using the

boolean last

parameter to indicate the final fragment (see onText method).

<code/**
 * WebSocket message listener
 *
 * @author L.cm
 */
public class WebSocketListener implements WebSocket.Listener {

    @Override
    public void onOpen(WebSocket webSocket) {
        // WebSocket connected
    }

    @Override
    public CompletionStage<?> onBinary(WebSocket webSocket, ByteBuffer data, boolean last) {
        // Binary message
        return WebSocket.Listener.super.onBinary(webSocket, data, last);
    }

    @Override
    public CompletionStage<?> onPing(WebSocket webSocket, ByteBuffer message) {
        // Received Ping frame
        return WebSocket.Listener.super.onPing(webSocket, message);
    }

    @Override
    public CompletionStage<?> onPong(WebSocket webSocket, ByteBuffer message) {
        // Received Pong (heartbeat) message
        return WebSocket.Listener.super.onPong(webSocket, message);
    }

    @Override
    public CompletionStage<?> onClose(WebSocket webSocket, int statusCode, String reason) {
        // Received Close frame, input side closed
        return WebSocket.Listener.super.onClose(webSocket, statusCode, reason);
    }

    @Override
    public void onError(WebSocket webSocket, Throwable error) {
        // Error occurred
    }

    private List<CharSequence> parts = new ArrayList<>();
    private CompletableFuture<?> accumulatedMessage = new CompletableFuture<>();

    @Override
    public CompletionStage<?> onText(WebSocket webSocket, CharSequence message, boolean last) {
        System.out.println(message);
        parts.add(message);
        // Request next message
        webSocket.request(1);
        if (last) {
            // Process whole message when last fragment
            processWholeText(parts);
            parts = new ArrayList<>();
            accumulatedMessage.complete(null);
            CompletionStage<?> cf = accumulatedMessage;
            accumulatedMessage = new CompletableFuture<>();
            return cf;
        }
        return accumulatedMessage;
    }

    /**
     * Process the whole message
     *
     * @param parts List of message fragments
     */
    private static void processWholeText(List<CharSequence> parts) {
        parts.forEach(System.out::println);
    }
}
</code>

3. Sending Messages

Sending supports text (

sendText

) and binary (

sendBinary

) messages; pay special attention to the

last

parameter, which marks whether the frame is the final one, useful for large payloads such as images or files that need to be split and reassembled on the server side.

<code// WebSocket connection
WebSocket webSocket = future.join();

// Whether this is the last data frame for large messages
boolean last = true;

// Send a text message
webSocket.sendText("mica 666!!!", last);

// Send a binary message
byte[] data = "pig 666!!!".getBytes(StandardCharsets.UTF_8);
webSocket.sendBinary(ByteBuffer.wrap(data), last);
</code>

4. Complete Example

Enough talk, here’s the code:

<codeWebSocket webSocket = HttpClient.newHttpClient()
    .newWebSocketBuilder()
    .buildAsync(URI.create("ws://121.40.165.18:8800"), new WebSocketListener())
    .join();

// Simulate periodic message sending
Timer timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        webSocket.sendText("mica 666,pig 666!!!", true);
    }
}, 3000, 3000);
</code>

Using Java 11 HttpClient to receive and send messages is very easy.

Javabackend developmentWebSocketHttpClientJava11
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.