Monday 12 May 2014

Chat Application in Java EE 7

Introduction

One of the new technologies which are introduced in Java EE version 7, is the WebSocket protocol.  With this protocol, it becomes easy to push any message from the server to the connected clients.  You no longer need the request - response model of HTTP but can send direct messages to the other peer.

The typical application for that protocol is a chat application. Any message send from a client to the server is pushed to all connected clients on that moment.

This text explains how you can create such a chat application with Java EE 7 with very few code lines.

WebSocket

First a bit of background about the protocol.  It uses the possibility of the Upgrade facilities of the HTTP protocol. This option was already foreseen in 1999 when the HTTP 1.1 spec was finalised.  Of course, at that time there was no one thinking about something like the WebSocket protocol but the spec has a part about the Upgrade of the HTTP protocol.

When the client sends an upgrade request to the server, by specifying the correct header values, it can ask for the switch to a certain protocol. Below is an example of a request for the upgrade to the WebSocket protocol.

GET HTTP/1.1
Upgrade: websocket

Connection: Upgrade


If the server accepts the request, it sends the confirmation of it to the client and from the on, the communication between the client is longer performed by the HTTP protocol but by the new one.

In case of the WebSocket protocol it is a bi-directional, full duplex communication over a single tcp connection.

Bi-directional means that the client and the server, although you don't use the terminology within WebSocket, can take the initiative to send information to the other party. And by default, there is no response expected in return.  This is in contrast to the HTTP protocol which is based on the request - response model where the client sends a request to the server and expect an answer for his question. With the WebSocket protocol it is just a push of data to the other side.

Full duplex means that there can be simultaneous communication between the 2 sides without interfering with each other.  The client, in HTTP terminologies before the upgrade started, can send information on the same time the server decides the send some bytes over the wire.  And both data arrives without any problems at the other side.

Server side

So let us create the server side of our chat application.  The amount of code we have to write is very minimal.  We can mark any POJO class as a WebSocket endpoint by using the annotation @ServerEndpoint. There is no need to implement any interface or extent of a parent class.

In this class we can mark a method which takes a String and javax.websocket.Session as parameter as the method which gets executed when the endpoint receives a message.

Below is all the code which is required for the server side of the chat application.

@ServerEndpoint("/bejug") 
public class ChatServer { 
 
    @OnMessage 
    public void onMessage(String message, Session session) { 
        for (Session s : session.getOpenSessions()) { 
            try { 
                s.getBasicRemote().sendText(message); 
            } catch (IOException e) { 
                e.printStackTrace(); 
            } 
        } 
    } 
} 

The method just redistribute the incoming message to all connected clients.  Those can be retrieved from the Session parameter.
With the Basic version I used here, you can send the message synchronously.  There exists also an asynchronous version which is not needed here since we are just sending small messages back and forth.

Client side

The typical client side of the chat application is a browser, but can also be any other client which support the WebSocket protocol.  Internet Explorer supports it since version 10, Firefox and Chrome are supporting it already some time.  Around 70% of the people who is surfing today does this with a browser which supports the WebSocket protocol (see http://caniuse.com/websockets)

So let us create a very simple and minimalistic WebPage which uses plain JS to have our client.

A WebSocket connection can be created by using the new WebSocket(“”) statement.  We can specify the callback functions which are executed when the connection is established, the onopen callback and the onmessage callback is called when the client receives a message.

The onopen is used in our example to send the message to all other clients that a new person has joined the group.   And the on message callback needs to display the new message on the screen.

The send() function is used to send some text to the server and thus to all connected client.  The complete code of the chat client is shown below.

<head lang="en"> 
    <meta charset="UTF-8"> 
    <title>BEJUG chat</title> 
    <script type="text/javascript"> 
        var connection; 
        function startChat() { 
            if ("WebSocket" in window) { 
                connection = new WebSocket("ws://localhost:8080/chat/bejug"); 
                connection.onopen = function () { 
                    connection.send(document.getElementById("name").value + " has joined"); 
 
                }; 
                connection.onmessage = function (evt) { 
                    document.getElementById("msgs").innerHTML += evt.data + '<br/>' 
                }; 
 
            } 
            else { 
                // The browser doesn't support WebSocket 
                alert("WebSocket NOT supported by your Browser!"); 
            } 
        } 
        function sendMessage() { 
            connection.send(document.getElementById('name').value + ' says : ' + document.getElementById('msg').value); 
        } 
    </script> 
</head> 
<body> 
 
    <h1>BeJUG chat</h1> 
    Messages 
    <div id="msgs"></div> 
    <hr/> 
    <input type="text" id="name"/> 
    <button type="button" onclick="startChat()">Join</button> 
    <br/> 
    <input type="text" id="msg"/> 
    <button type="button" onclick="sendMessage()">Send</button> 
</body> 

Conclusion

With the addition of the WebSocket protocol, there are now 3 ways of interacting with a Java EE 7 server.
Servlets which are already used since the first days of web development with Java but still very important as they are the base of many technologies which uses the front controller pattern like JavaServer Faces.
The second option, JAX-RS or rest style way of working with JSON, is basically also servlet based so you could classify it with the previous category.  But since it importance for the communication with smartphones, it deserves a category of there own.
And the latest addition is the push type of communication with the WebSocket protocol where you need independent communication between peers.