I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Introduction

AsyncHttpClient (AHC) is a library, based on Netty, created to easily execute asynchronous HTTP calls and communicate over the WebSocket protocol.

In this quick tutorial, we’ll see how we can start a WebSocket connection, send data and handle various control frames.

2. Setup

The latest version of the library can be found on Maven Central. We need be careful to use the dependency with the group id org.asynchttpclient and not the one with com.ning:

<dependency>
    <groupId>org.asynchttpclient</groupId>
    <artifactId>async-http-client</artifactId>
    <version>2.2.0</version>
</dependency>

3. WebSocket Client Configuration

To create a WebSocket client, we first have to obtain an HTTP client as shown in this article and upgrade it to support the WebSocket protocol.

The handling for the WebSocket protocol upgrade is done by the WebSocketUpgradeHandler class. This class implements the AsyncHandler interface and also provides us with a builder:

WebSocketUpgradeHandler.Builder upgradeHandlerBuilder
  = new WebSocketUpgradeHandler.Builder();
WebSocketUpgradeHandler wsHandler = upgradeHandlerBuilder
  .addWebSocketListener(new WebSocketListener() {
      @Override
      public void onOpen(WebSocket websocket) {
          // WebSocket connection opened
      }

      @Override
      public void onClose(WebSocket websocket, int code, String reason) {
          // WebSocket connection closed
      }

      @Override
      public void onError(Throwable t) {
          // WebSocket connection error
      }
  }).build();

For obtaining a WebSocket connection object we use the standard AsyncHttpClient to create an HTTP request with the preferred connection details, like headers, query parameters or timeouts:

WebSocket webSocketClient = Dsl.asyncHttpClient()
  .prepareGet("ws://localhost:5590/websocket")
  .addHeader("header_name", "header_value")
  .addQueryParam("key", "value")
  .setRequestTimeout(5000)
  .execute(wsHandler)
  .get();

4. Sending Data

Using the WebSocket object we can check whether the connection is successfully opened using the isOpen() method. Once we have an open connection we can send data frames with a string or binary payload using the sendTextFrame() and sendBinaryFrame() methods:

if (webSocket.isOpen()) {
    webSocket.sendTextFrame("test message");
    webSocket.sendBinaryFrame(new byte[]{'t', 'e', 's', 't'});
}

5. Handling Control Frames

The WebSocket protocol supports three types of control frames: ping, pong, and close.

The ping and pong frame are mainly used to implement a “keep-alive” mechanism for the connection. We can send these frames using the sendPingFrame() and sendPongFrame() methods:

webSocket.sendPingFrame();
webSocket.sendPongFrame();

Closing the existing connection is done by sending a close frame using the sendCloseFrame() method, in which we can provide a status code and a reason for closing the connection in the form of a text:

webSocket.sendCloseFrame(404, "Forbidden");

6. Conclusion

Having support for the WebSocket protocol, besides the fact that it provides an easy way to execute asynchronous HTTP requests, makes AHC a very powerful library.

The source code for the article is available over on GitHub.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS