Vert.x for real time web apps in Java
Posted On July 2, 2016 by Geeta Priya filed under Enterprise
The explosion in the number of mobile clients to applications, like real time chat, collaborative document editing, massively multiplayer online (MMO) games, stock trading applications etc-called “C10K” problem- and the advent of multi-core processors had their impact on software industry. Mostly our web applications have been using HTTP which follows Request-Response cycle, where only the client can initiate a request. Server can only send a response to the request in a separate connection. The half-duplex HTTP connections with their overheads could not meet the needs of these new apps. The shared memory multi-threaded model of synchronous Servlet technology also could not scale well to meet their demands. There is a growing shift to asynchronous, functional and concurrent programming and wider adoption of the Web-Socket to handle the situation. The new found of popularity of Erlang and Lisp languages and the advent of reactive frameworks like Node.js, Netty, Akka are indicators of this new trend. Vert.x, Reactor from Spring Source, Avatar from Oracle are also attempts in this direction. Spring is also expected to become reactive from version 5 –probably built on top of NIO and Netty like Vertx. In short the reactive frameworks have become main-stream and Web-socket is increasingly used to tackle “C10K”.
The soft real time apps require high speed connections with low latency. They also require a full- duplex connection in which server can push data when there is some data for the client even without the client asking for it. Take the example of Twitter or FaceBook Notifications. They are examples of soft real time apps. You will be notified of developments relevant to you even without you asking for it. To build such a real-time functionality into our app, WebSocket standard, which makes use of a TCP, a lower level Transport layer protocol has been laid down. It is a standard communication/wire protocol for bidirectional fully duplex connections. In other words, as against the separate connections used by client and server in HTTP request and response, both the server and the client will be using the same TCP connection when web-socket is used. HTTP is used only for initial handshake and there after messages are pushed as streams without over-heads such as cookies headers etc in TCP connections. This reduces the size of the data passed and as well as the time taken-latency. The extra over-head is only ping-pong frames to keep the connection alive.
Verticles are chunks of code that get deployed and run by Vert.x. Verticles can be written in any of the languages that Vert.x supports and a single application can include Verticles written in multiple languages. The different Verticle instances communicate with each other by sending messages on the event bus. They can be broadly classified into two types. 1) Standard Verticles: They are assigned an event loop thread when they are created and the start method is called with that event loop. Normally we have to code event-handlers within the Verticle which will be called later only after the concerned event has happened. Vert.x sees to it that those handlers, when called, will be executed on the same event loop. In other words all the code in your Verticle instance is always executed on the same event loop. Thus you can write all the code in your application as single threaded and let Vert.x worry about the threading and scaling 2) A worker Verticle: It is just like a standard Verticle but it’s executed not using an event loop, but using a thread from the Vert.x worker thread pool. Worker Verticles are designed for calling blocking code, and hence they won’t be run on event loops.
Web-Socket Emulation libraries
There are no external dependencies. So there is no need for a dependency management tool like Maven and we will use the local Vertx installation. We will run our Java sample using runtime “vertx”. As mentioned in the earlier article, no prior pre-compilation is necessary and the Java file will be compiled on the fly and run. No elaborate directory structure is required. Just create a folder “chat” and code a java file in it. The default directory for static content is “webroot”. The “index.html” can be created under it. The client side ”vertx-event-bus.js”referred above should also be placed in it. The code for Server.java is given below:
Our Verticle implements a simple, real-time, multiuser chat. Anyone can connect to the chat application on port 8080 and type messages. The messages will be rebroadcast to all connected users via EventBus-SockJs bridge.
Vertx-web provides a Router object. To it we have to add routes and provide handlers so that it can match the incoming request and forward it to the appropriate handler. Here only built-in handlers- StaticHandler and SockjsHandler- are used for requests for static file and for requests from a Sockjs client respectively.
- The static method create() creates an instance of SockJS handler. As the bridge() method, bridges the SockJS handler instance to an event-bus instance , the handler instance is able to handle the traffic for event-bus. But as mentioned above, the client should use “vertx- event-bus” client side library. Event-bus also acts like a fire-wall. Only events from and to certain addresses are allowed in and out of Event-bus.
- Recall in WebSocket protocol, HTTP is used for initial handshake. The TCP connection used by the client to make a request for protocol upgrade becomes a permanent connection, when the server accepts the request. Thereafter it is used by both the server and the client for “pushing” messages. HTTP server is necessary for establishing the connection. Thereafter the SockJS handler pushes messages from EventBus into SockJS sockets and transports messages from SockJS sockets to specified addresses in Event-bus. The bridge() installs a built-in SockJS socket handler which takes SockJS traffic and bridges it to the event bus, thus allowing you to extend the server-side Vert.x event bus to browsers
- The consumer() method in the event-bus is used to register the handler for incoming messages
- Publish() method is used to publish the message to all clients. More than one client can register with an address to receive messages from that address- remember “publish-subscribe” and “topic” in messaging systems.
The above code creates a micro-service/self contained chat service in Java. There is no need for any web-container or application server. There is no JEE (Servlet or EJB.) Only Java APIs are used, apart from the classes in the Vertx library. It can be run anywhere if the system has Java and Vertx installed. In an earlier article we saw how to use Maven to build a fat.jar of our app, which can be run even without any local Vertx installation.
View file: The code for the html file to access the above service is given below:
- The alternative syntax for document.ready() is used.The code is enclosed within the function that is executed after the page is loaded.
- To the constructor of EventBus, the uri is passed, so that the instance can connect to the event-bus.
- Within the handler for onopen event, handler for registerHandler event is registered.This handler executes/handles incoming message.
- When the form is submitted the framework will look for default action.To prevent that preventDefault() is called.The callback function passed to submit() is called when the form is successfully submitted.
- Publish() in event-bus is used to publish the message to the address in event-bus.