Sunday, 8 May 2016

WebSockets


In this article i want to discuss about the websocket implementation and writing a sample web application on HTML5 web sockets.In Web applications we generally make use of servlets,jsps HTTP protocol for the communication between client and server.Now a days we are using web sockets programming to develop web applications.So what is the main reasons to use web sockets and what are the demerits of HTTP protocol which is pushing the developers to make use of web sockets.

Why we need to use web sockets ?

1.Two Way Communication or Bidirectional Communication : 
   By using HTTP protocol  two way communication or bidirectional communication  is not possible.Like server cannot send data to client without client request .

2.Header Size : 
    In normal http request and response unnecessary Header information, for every request  and cookies are added to the request and sent to the server  and vice versa which is not required  this will increases the Header size.This will lead to high response time latency because of HEADER size.

Sample HTTP request Header :
Host                 --10.96.54.40:8080
user-agent           --Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0
accept               --text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language      --en-US,en;q=0.5
accept-encoding      --gzip, deflate
referrer             --http://10.96.54.40:8080/HttpHeadersInfo/
cookie               --JSESSIONID=0D941D31966CDA18AB8CCEC5F248A3F3
connection           --keep-alive
content-type         --application/x-www-form-urlencoded
content-length       —20


Sample HTTP response Header

[HTTP/1.1 200 OK]
Server -- [Apache-Coyote/1.1]
Set-Cookie -- [JSESSIONID=0D941D31966CDA18AB8CCEC5F248A3F3; Path=/HttpHeadersInfo/; HttpOnly]
Content-Length -- [414]
Date -- [Thu, 23 Jul 2015 11:54:22 GMT]
Content-Type -- [text/html;charset=ISO-8859-1]

Server identifies the client by cookie JSESSIONID and every time all this information is sent to the server. This is slightly overburden.

To overcome above issues we have to work with web sockets.

Web Sockets :
 Websockets were initially implemented in HTML 5 later implemented  in java 7 api.
 The protocol used by websocket is TCP based

Why(Uses of web sockets   ) :
  A WebSocket is asynchronous, bidirectional, full-duplex messaging implementation over a single TCP connection
  We can achieve quick response from the client by using web sockets which is called as low-latency. Client gets quick response from the server because of header size and dedicated connection between client and server.
  Web Sockets provide a persistent connection between a client and server that both parties can use to start sending data at any time.
Two way communication : client can send the data to server as well as the server can send response back to client without any client request.(Which is not possible 

How it works :
                

As per the above diagram


  •  When we deploy and start the  Server web socket it is ready to accept the request from the client on particular url. For ex: ws://localhost:8080/mycontextroot/hello.
  •  When client web socket try to connect this url  as per above diagram step 1 .The first request will be normal  HTTP request  in which is client requests for web socket upgradation.(HTTP to TCP)
  •  Client sends the first HTTP request to the server with the following header information requesting websocket connection
GET ws://localhost:8080/myApp/ HTTP/1.1
Origin: http://localhost:8080
Connection: Upgrade
Host: websocket.example.com
Upgrade: websocket
·   
       Here ws: is web socket schema it is like http and for secure web socket connection wss: like https.
·         This is called as HANDSHAKE which contains important information to identify the client is requesting for a web socket connection. This can be identified by two parameters
               Connection : Upgrade
                Upgrate : websocket
·         We can identify from above header info
                Connection :Upgrade means the connection requesting for an  upgrade
                Upgrate : websocket means the upgrade is to websocket.
·         Server identify the above commands and send a confirmation response header  as the connection is upgraded to web socket .This will inform as they are moving to Web socket connection. As per above  diagram step 2.
HTTP/1.1 101 WebSocket Protocol Handshake
Date: Wed, 16 Oct 2013 10:07:34 GMT
Connection: Upgrade
Upgrade: WebSocket

·         When the client receives this information it is confirmed that HANSHAKE is successfull. A dedicated tcp connection is established between client and server .So that the server and client can send data in both directions.No need to send any header information as it is dedicated connection to client and server. As per above  diagram step 3.
·         Once the connection is closed the tcp connection will be closed.

Now we will develop the sample socket application  using eclipse and tomcat 8 server.
·         Download and install the latest eclipse .
·         Now open the eclipse and create dynamic web project.(File — New — Other — Dynamic web Project — Enter Project Name (WebSocketExample)— select the Target Runtime — Finish)
·         Create a package “com.javaAngels”
·         Create a normal java class(ServerWebSocket) and copy the following code

package com.javaAngels;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/ServerWebSocket")
public class ServerWebSocket {

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("-- THIS IS onOpen or Onconnect method  ---" + session.hashCode());
    }

    @OnMessage
    public void onMessage(String message, Session session) throws Exception {
        System.out.println("-- THIS IS On Message method----" + session.hashCode());
        session.getBasicRemote().sendText("Hi I am Server and you send me a message -------" + message);
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("-- THIS IS On close  method----" + session.hashCode());
    }

}

·         Create index.html file and place the following code

<!DOCTYPE html>

<html>
<head>
<title>Client Socket</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
       <div>
              <input type="text" id="messageinput" />
       </div>
       <div>
              <button type="button" onclick="openSocket();">Open</button>
              <button type="button" onclick="send();">Send</button>
              <button type="button" onclick="closeSocket();">Close</button>
       </div>
       <!-- Server responses get written here -->
       <div id="messages"></div>
       <!-- Script to utilise the WebSocket -->
       <script type="text/javascript">
            var webSocket;
            var messages = document.getElementById("messages");
            function openSocket(){
                // Ensures only one connection is open at a time
                if(webSocket !== undefined && webSocket.readyState !== WebSocket.CLOSED){
                    writeResponse("WebSocket is already opened.");
                    return;
                }
                // Create a new instance of the websocket
                webSocket = new WebSocket("ws://localhost:8080/WebSocketExample/ServerWebSocket");
                /**
                 * Binds functions to the listeners for the websocket.
                 */
                webSocket.onopen = function(event){
                    // For reasons I can't determine, onopen gets called twice
                    // and the first time event.data is undefined.
                    // Leave a comment if you know the answer.
                    if(event.data === undefined)
                        return;

                    writeResponse(event.data);
                };
                webSocket.onmessage = function(event){
                    writeResponse(event.data);
                };
                webSocket.onclose = function(event){
                    writeResponse("Connection closed");
                };
            }
            /**
             * Sends the value of the text input to the server
             */
            function send(){
                var text = document.getElementById("messageinput").value;
                webSocket.send(text);
            }
            function closeSocket(){
                webSocket.close();
            }

            function writeResponse(text){
                messages.innerHTML += "<br/>" + text;
            }
           
        </script>

</body>
</html>

·         The final project structure looks like                                                            
                                                                             

·         Download tomcat 8 from http://tomcat.apache.org/  and configure it in eclipse.
·         Now run the application  by Right click on project  --  Run As  -- Run on Server – Finish.

Project Explanation :

·         Web Socket will have lifecycle annotations  like @onOpen,@onMessage and @onClose.
·         Whenever a socket is established method with onOpen annotation  will be called.This is called only once per a socket.
·         Once the Handshake is implemented and tcp connection is opened .The client and server will communicate with each other  and send data  by using  @ onMessage  method..
·         onClose will be called once the socket is closed.
·         When it comes to our project  ,
·         Once we deploy our application the server socket is ready to accept the requests. Client can establish sockets on  @ServerEndpoint value
·         Enter the Url http://localhost:8080/WebSocketExample/ in your browser(chrome ).
·         We can see  
       
·       This is a normal HTTP request we can observe the request details in Chrome browser.(press F12 button – Network --  Click on Name WebSocketExample observe the Header information)



·         Click on “open” button  the index.html.
  •         If you look at the code in index.html  we can see “open” button is calling openSocket() method which  will create a socket on “ws://localhost:8080/WebSocketExample/ServerWebSocket”.(Nothing but our server socket). Which will  the onOpen() method in “ServerWEbSocket.java”.
  •    This is called “HAND SHAKE” request .Observer the following  type attribute which confirms  websocket  creation.






·         Client requested for upgrade to socket and server responded to the socket upgradation.This is called Handshake Success.




·         If you try to connect to the wrong or unavailable  Socket , we can find the Hand shake Failure response as follows)(Ex: ws://localhost:8080/WebSocketExample/ServerWebSocketWrong)

·         Once the HANDSHAKE is successful server create a TCP connection to the client and they can communicate with each other.
·         websocket.send(“TEXT MESSAGE”) message is used to send message from UI or html  and  session.getBasicRemote().sendXXX(“MESSAGE”) is used in server side to send messages.(where session object is the session related to a particular connected socket to whom we want to send a message)
·         Once we enter a message and click on send button which will call the websocket.send(“TEXT MESSAGE”) from client and in server side @onmessage method will receive this message.
·         The same way server sends the message back to the client socket  by using session.getBasicRemote().sendXXX(“MESSAGE”)  method wich will be received by webSocket.onmessage() method.
·         Once we click on close button websocket.close() method is called and in server socket @onClose() nwill be called which will end the TCP connection.