WEBSOCKET VERSUS COMET – REAL-TIME WEB APPLICATIONS

Introduction

Many web application developershave tried to develop a high performance web application with real-timebehaviors. A common example of such an application could be a communication webplatform like a chat application. A message sent by a user should betransmitted in real-time to other users.

Years ago I tried to develop achat web application but until now it has not been so easy to achieve. I wouldlike to show you how easily and clearly it can be implemented today.
There will be a comparison of the different approaches to develop a real-timeweb application which will show that it has never been easier to achieve itbefore.

The approaches I want to compareare the “new” WebSocket technology and the “old” Comet approach. First you willsee how difficult it was and how easy it is today to write a smallcommunication platform. You will also get the easy and clear source code of thecommunication platform through the WebSocket technology. This article does notcover a complete WebSocket description but a short insight of the WebSockettechnology advantages and a practical usage.

Challenges

The biggest challenge to achievereal-time on web applications is the application layer protocol HTTP. Theprotocol is a request-response protocol where:

  • only the client is able to send a request and
  • only the server is able to send a response to the previous sent client-request.

Therefore only the client is ableto start the communication. Without a previous received client-request theserver is not able to communicate with the client.

Usually HTTP uses TCP as transportlayer protocol. The TCP connection will be closed after a request-responsephase. It has to be reinitiated by the client in case the client wants tocommunicate with the server again.

There are other solutions likeHTTP-polling but with such an approach you can only achieve near-real-timebehavior because the client has to poll the server for new updates with adefined frequency. You could set the poll frequency very low but in this casethe application would not perform very well.

Usually with HTTP the TCPconnection is closed after each request-response phase. Another challengeoccurs when the client and server are connected permanently which causeresource problems on the server-side because of keeping open all connectionsfor each client.

We do concentrate on “real” webapplications and not on web applications which embed rich client applicationslike a swing application on an HTML site via applets or by using JNLP. Ofcourse there is no barrier for rich client applications to transmit data inreal-time in both directions by using the TCP transport-protocol directly andnot the HTTP application-layer-protocol.
After showing all the challenges I promise that there is a good solution withthe new WebSocket technology. But let us first see how difficult it had beenfor developers before this new technology was developed.

Comet

Comet is not a technology but onlya model which uses the HTTP protocol and which tries to hide the limitationsdue to its incapacity starting the communication on server side by sending arequest to the client. Comet tries to hide this limitation by simulating aserver-push request.

The Comet model consists of twosteps. In the first step:

  • the client sends a request to the server and
  • the server holds this request open until there is data available for the client.

In the second step:

  • data is sent from the server to the client and
  • a new request is started by the client.

With this approach the server cansend data to the client immediately.

This technique is calledlong-polling. The client polls data from the server by sending a requestremaining open for a long time until data is available for sending to theclient at once.

At first sight this techniquelooks good but it is not so easy to implement due to some problems with it. Forexample there are timeouts if the client-request is open too long. In the nextstep the client has to re-initiate the polling. In addition the behavior oftime-outs can vary for different environments. Also an open request on serverside which is not closed requires much of server resources.

I think now it should be clear forus that this technique could be only a hack to avoid polling with a definedfrequency. There is another efficient solution to achieve real-time behaviorsin web applications.

WebSockets

As I supposed that you are waitingfor the best solution for implementing a real-time communication webapplication, I will introduce the new WebSocket technology to you.

The new WebSocket technology hasnothing to do with HTTP but only the WebSocket handshake is interpreted by HTTPservers as an http upgrade-request. While Http is commonly using TCP, alsoWebSocket is based on TCP.

For HTTP the TCP connection isusually closed after every request-response phase. In contrast the WebSocketconnection is started by the client by sending a connection request to theserver and after the connection is established the TCP connection is neverclosed. While the connection is kept open the client and the server are able tosend data mutually. Also WebSockets support full duplex allowing thetransmission of data in both directions simultaneously similar to TCP.

In order to save resources onserver-side the Java Reference Implementation (RI) of the WebSocket protocoluses asynchronous handling. It is not necessary to keep running a thread perclient-connection on the server-side.

As the WebSocket protocol waspublished as IETF standard there are many technologies and libraries supportingit. Since Java EE 7 implemented the WebSocket protocol in the RI – code nameTyrus – also Glassfish supports it. In addition the WebSocket protocol issupported by HTML5 and by a wide range of browsers. Also in Androidapplications you can use it by adding different libraries likeautobahn-library. I am not surprised thatthe support of WebSockets is mature and I think it will become better in thefuture.

Example – communication web application with WebSockets

Now we will implement our owncommunication web application. The application consists of a simple websiteshowing a textarea field, an input field and a send button. The textarea fieldshows all messages which are sent by the connected clients. With the inputfield and the send button a message can be sent by a client.

As mentioned before this applicationis implemented with WebSockets in order to create a real-time application. Allmessages will be shown to every connected user immediately after sending.

Server

The server is implemented with theJava 7 JEE RI of the WebSocket technology tyrus. As server we are using thetyrus standalone server which is using the grizzly web-container not to deploythe web application to the Java 7 EE Glassfish server.
All dependencies we get through the following maven dependencies:

               <dependency>
                   <groupId>javax.websocket</groupId>
                   <artifactId>javax.websocket-api</artifactId>
                   <version>1.0</version>
               </dependency>
               <dependency>
                   <groupId>org.glassfish.tyrus</groupId>
                   <artifactId>tyrus-server</artifactId>
                   <version>1.2.1</version>
               </dependency>
               <dependency>
                   <groupId>org.glassfish.tyrus</groupId>
                   <artifactId>tyrus-container-grizzly</artifactId>
                   <version>1.2.1</version>
               </dependency>

Now we have all external librarieswe need in order to implement a standalone server supporting the WebSockettechnology. Let us start to implement the deployable web application. All weneed is the following code snippet.

@ServerEndpoint(value ="/meeting-room")
publicclassForwardServer{
 
    @OnOpen
    publicvoid onOpen(Session session){
        for(Session open : session.getOpenSessions()){
               try{
                       open.getBasicRemote().sendText("new user connected.");
               }catch(IOException e){
                       thrownewRuntimeException(e);
               }
        }
    }
 
    @OnMessage
    publicvoid onMessage(String message,Session session){
        for(Session open : session.getOpenSessions()){
               try{
                       open.getBasicRemote().sendText("msg: "+message);
               }catch(IOException e){
                       thrownewRuntimeException(e);
               }
        }
    }
 
    @OnClose
    publicvoid onClose(Session session){
    }
}

We call the class ForwardServerbecause the server is forwarding the incoming messages to all connectedclients. The endpoint is reachable through ../meeting-room.

If a client connects with theserver all clients receive the message “new user connected”. This isimplemented by the onOpen-Method. With the Session-argument of theonOpen-Method you get all Sessions of the connected clients by callingsession.getOpenSessions(). And with the corresponding client-session you cansend messages to all connected clients.

If a user sends a message allclients connected to the server get this message which is implemented in theonMessage-Method in a similar way by iterating over all connected clients andby sending the received message to all clients.

After having implemented theforward server we have to deploy it on the standalone server. This isimplemented by the following code snippet. In addition the standalone-server isstarted.

publicclassWebSocketServer{
 
    publicstaticvoid main(String[] args){
        runServer();
    }
 
    publicstaticvoid runServer(){
        Server server =newServer("localhost",80,"/websockets",ForwardServer.class);
        try{
            server.start();           
            synchronized( server){
               server.wait();
            }        
        }catch(Exception e){
            thrownewRuntimeException(e);
        }finally{
            server.stop();
        }
    }
}

Now the server implementation isfinished and we can reach our forward server by the following url:ws://localhost/websockets/meeting-room

Client

Let us implement the client side.We are not using a Java client but a simple JavaScript client. Fortunatelyalmost every new browser will support the new WebSocket technology.

As mentioned before the webapplication is very easy to implement. As you can see it is very easy toinstantiate a WebSocket in JavaScript. Theconnect()-methodinstantiates a WebSocket and implements theonmessage() -methodwhich only appends the receiving message to antextarea field.The sendmessage()-method uses the WebSocket and sends the messagefrom theinput field to the server.

<html>
    <head>
        <title>meeting room</title>
        <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
        <scripttype="text/javascript">
               // Websocket Endpoint url
               var endPointURL ="ws://localhost/websockets/meeting-room";
               var webSocket;
                
               function connect (){
                    webSocket =newWebSocket(endPointURL);
                   webSocket.onmessage =function(event){
                       var messagesArea = document.getElementById("messages");
                       var message = event.data +"\r\n";
                       messagesArea.value =  message + messagesArea.value;
                   }
               }
                
               function disconnect (){
                   webSocket.close();
               }
                
               function sendmessage(){   
                   webSocket.send( document.getElementById("messageInput").value);
                   document.getElementById("messageInput").value ="";
               }
        </script>
    </head>
    <bodyonload="connect();"onunload="disconnect();">
        <h1>meeting room</h1>
        <textareaid="messages"style="width:500px;height:200px"disabled="true"></textarea>
        <div>
            <inputid="messageInput"style="width:440px;"onkeydown="if(event.keyCode ==13) sendMessage();"/>
            <inputtype="button"value="send"onclick="sendmessage();"/>
        </div>
    </body>
</html>

For a Java client supporting theWebSocket technology you can do this by adding the following dependency.

               <dependency>
                   <groupId>org.glassfish.tyrus</groupId>
                   <artifactId>tyrus-client</artifactId>
                   <version>1.2.1</version>
               </dependency>

The implementation of a Javaclient is as easy as the implementation of the JavaScript client. The clientclass is annotated with@ClientEndpoint and deployed by the TyrusClientManager. After connecting to the server it will be sent a short messageto the client. In a next step the client listens for other messages which willbe printed to the standard console.

@ClientEndpoint
publicclassClient{
 
        privateSession sess;
 
    @OnOpen
    publicvoid onOpen(Session session){
        sess = session;
    }
 
    @OnMessage
    publicvoid onMessage(String message,Session session){
        System.out.println("msg:"+message);
    }
 
    publicvoid sendMessage(String message)throwsIOException{
        sess.getBasicRemote().sendText( message);
    }
 
    publicstaticvoid main(String[] args)throwsException{
        ClientManager client =ClientManager.createClient();
 
        finalClient c =newClient();       
        client.connectToServer( c,new URI("ws://localhost/websockets/meeting-room"));
 
        c.sendMessage("send data by java-client ...");
 
        synchronized(client){
               client.wait();
        }
    }
}

Conclusion

Hopefully I could show how easy itis to implement a real-time web application with the new WebSocket technology.In contrast to the Comet model the WebSocket technology can achieve real-timebehavior for web applications without the misuse of the HTTP protocol.

With the WebSocket technology adeveloper gets a new tool to make a web application more attractive for manyweb application users. Before the WebSocket technology was born there had beena solution to achieve a high performance real-time web application with theComet-model but it has never been easier to achieve by WebSockets.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章