Skip to content

How to quickly start with WebSockets in Vert.x and Java

Hi there! In this short post, I would like to demonstrate you, how to write a very simple Websockets server with Vert.x and Java. Basically, it is not a rocket science, you even don’t need to have additional dependencies – only Vert.x Core. Moreover, it is easy! Let start!

Handling websockets with Vert.x

Websockets protocol offers a fast, secure, bi-directional, full duplex communication over a single TCP connection. We can use them, when we need real time messaging with low latency. Take a look on the graph below:

You can note, that after an initial handshake, client and server create persistent bi-directional communication (full duplex). This is handy, when you need to write something real time, like messaging app.

Let’s write a very simple websockets example: the client would send to the server any string and server responds with reversed version. So if clients sends hello, server answers olleh. To do this, we don’t need any libraries, but only Vert.x Core, as Vertx HttpServer has all required functionality. Add Vert.x Core dependency to your app’s pom.xml:

<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-core</artifactId>
    <version>3.7.1</version>
</dependency>

Or if you are using Gradle:

dependencies {
 compile 'io.vertx:vertx-core:3.7.1'
}

And then, create a new Verticle: VertxSocketsVerticle. There, we would do following:

  1. Create new HttpServer
  2. Append WebsocketHanlder to the HttpServer
  3. Assign handler to the Websockethandler
  4. Start HttpServer on port 8080

Take a look on the code snippet below:

public class VertxSocketsVerticle extends AbstractVerticle {

    @Override
    public void start() throws Exception {
        super.start();
        vertx.createHttpServer().websocketHandler(ws-> {
            ws.handler(buffer -> {
                        
                        //todo send reversed string back
                    }
            );
        }).listen(8080, res->{
            if (res.succeeded()){
                System.out.println("Created websocket server on port 8080");
            } else {
                System.out.println(res.cause().getLocalizedMessage());
            }
        });
    }

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(new VertxSocketsVerticle());
    }
}

Basically this is what we need. Inside start() method of the vertcile, we create new server and handle websocket connection. Websocket handler provides ServerWebSocket, that represents a server side websocket. With it, we can do operations and append handlers. Please take a look, that websocket handlers operate Buffers. In Vert.x, Buffers are a sequence of zero or more bytes that can read from or written to and which expand automatically as necessary to accommodate any bytes written to it. In other words, message, that is supplied by client would be represented as a Buffer and we can access it. In our example we do a very simple operation: read a message and return it back to client:

String reverse = new StringBuilder(buffer.toString()).reverse().toString();
Buffer response = Buffer.buffer(reverse);
ws.write(response);

We create a reversed string with StringBuilder and then write it back. Take a look, that we again use buffers for this – we can create new Buffer with static Buffer.buffer(String s) method. There is an alternative way to do it using writeTextMessage(String s) where we can write a string directly:

  • write (Buffer buffer) = write some data to the stream.
  • writeTextMessage(String text) = write a (potentially large) piece of text data to the connection. This data might be written as multiple frames if it exceeds the maximum WebSocket frame size.

Also, there are other handy methods in case you need to write frames or binary messages, you can explore more in Vertx docs. Basically, that is what we need. Let run our application and see what happens.

Testing websockets

When it comes to testing HTTP endpoints, the most obvious choice is to use Postman. However, websocket connections are still missed in Postman, so we need to use other options. There are several ways to test websockets, although I like to use wscat. This is a simple command line tool, that runs on Node. You need to install Node.js to run it. After you install this tool, it becomes incredibly easy to test websockets. Just run wscat with address of websocket server:

wscat -c ws://localhost:8080

Now, you can send messages to the websocket server and it would respond with reversed versions:

You can quit session by pressing Ctrl + C, but… What would happen after you disconnecting?

Finishing connection

For server – nothing. It would run. But you can handle disconnecting of user with these handlers:

  • endHandler(Handler endHandler)
  • closeHandler(Handler handler)

CloseHandler will be called when the WebSocket is closed, and after this callback, no more messages are expected. EndHanlder is called when the stream has ended, and there is no more data to be read. Let add them to our verticle:

vertx.createHttpServer().websocketHandler(ws-> {
            ws.handler(buffer -> {
                        String reverse = new StringBuilder(buffer.toString()).reverse().toString();
                        Buffer response = Buffer.buffer(reverse);
                        ws.write(response);
                    }
            );

            ws.endHandler(h-> System.out.println("End handler!"));

            ws.closeHandler(h-> System.out.println("Close handler"));

        }).listen(8080, res->{
            if (res.succeeded()){
                System.out.println("Created websocket server");
            } else {
                System.out.println(res.cause().getLocalizedMessage());
            }
        });

When you run this code, start and than disconnect wscat, you would note, that first is executed CloseHanlder, and after it, EndHanlder:

You can use them to handle disconnecting of clients. Note, that both supplies Void handlers, that means, there is no data provided by these handlers.

Conclusion

In this brief post, I showed that creating a websocket server with Vert.x is not a rocket science and basically takes a couple of lines of code. There are other handy methods, you can find in ServerWebSocket documentation and use them in your solutions. By the way, if you’d like to handle Websocket client with Java, you can use new Java 11 HttpClient, as it supports now Websockets. You can find more about Java 11 HttpClient in my tutorial. If you have any questions regarding Vert.x and Java programming, feel free to write me DM in Twitter. Have a nice day!

References

  • Joydip Kanjilal. How to work with Web Sockets in .Net (2016) InfoWorld, read here
Copy link
Powered by Social Snap