Sunday, October 26, 2014

Websockets and the real-time web, part III [The Client Side]

Link to Part I of the Article: http://ruminationsontechnology.blogspot.com.es/2014/10/websockets-and-real-time-web-part-i.html

Link to Part II of the Article: http://ruminationsontechnology.blogspot.com/2014/10/preview-websockets-and-real-time-web.html

The Client Side

Now that we visited the belly of the beast in part II of this article, let us complete the circle by taking a look at the client side of the implementation.

As noted in part II, the complete code for the tutorial in this article can be downloaded from Github, for Eclipse Luna or NetBeans 8.0.1.

As a quick refresher, we are implementing a web based monitor that reports, on real-time, the space availability of all the public parking lots owned by the fictional company A-Lotta-Parking.

The client side implementation will rely on:
  • JavaScript/jQuery
  • HTML5 
 And I assume that you have a basic working knowledge of them.

The HTML

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>A-Lotta-Parking</title>
        <script src="js/jquery/jquery-2.1.0.js"></script>
        <script src="js/zingchart/zingchart-html5-min.js"></script>
        <script src="js/zingchart/zingchart.jquery.js"></script>
        <script src="js/alottaparking.js"></script>

        <link href="css/alottaparking.css" rel="stylesheet">
    </head>
    <body>
        <nav id="buttons">
            <button id="btnOpenConnection">Open WS</button>
            <button id="btnStartMonitor" disabled>Start Monitor</button>
            <button id="btnStopMonitor" disabled>Stop Monitor</button>
            <button id="btnCloseServerConnection" disabled>Close WS</button>
        </nav>
        <section id="chart"></section>
        <section>
            <table>
                <thead>
                    <tr>
                        <th>N°</th>
                        <th>Lot Name</th>
                        <th>Capacity</th>
                        <th>Used Capacity</th>
                        <th>Used Percentage</th>
                    </tr>
                </thead>
                <tbody id="tableData">
                </tbody>
            </table>
        </section>
    </body>
</html>

Other than the mandatory includes in the head section, our index.html file has three blocks:

The header block, where there are four buttons for the control of the operation.

The first section block, where the monitoring chart will exist, and...

The second section block, where initially there is a simple html table skeleton, which will, during active operation, display the data related to the chart above it.

That was pretty straightforward.

The JavaScript

alotaparking.js

    function openSocketConnection ( ) {
        
        //   Create the WebSocket
        websocket = new WebSocket ( "ws://localhost:8084/A-Lotta-Parking/parkingLotUpdates" );

        //   When the server messages the client, we receive the message here.
        websocket.onmessage = function ( evt ) {

            var obj = $.parseJSON( evt.data );
            if ( obj.lotsMonitor !== undefined ) { processSnapshot   ( obj ); }
        };

        //   When the server closes the WebSocket, we receive the notification here.
        websocket.onclose = function ( evt ) {
            //alert("Server closed WebSocket");
        };

        //   Set html buttons state
        buttonStates ( "openedState" );

    }

    //   When the client requests to start the monitoring, we sent the "startMonitor" message here.
    function sendStartCommand ( ) {
        websocket.send ( "startMonitor" ); 

        //   Set html buttons state
        buttonStates ( "startedState" );
        
    }

    //   When the client requests to stop the monitoring, we sent the "stopMonitor" message here.
    function sendStopCommand ( ) {
        websocket.send ( "stopMonitor" ); 

        //   Set html buttons state
        buttonStates ( "stoppedState" );
    
    }

    //   When the client requests that the server close the websocket, we send the "closeConnection" here.
    //   
    //   Of course, as a client, we have the power to close the websocket connection from
    //   the client side using "websocket.close()". I just chose to do it in a different 
    //   fashion and politely request the server to do so on our behalf.
    //   
    //   In this tutorial, we are also using the other method, we are listening to the "beforeunload" event, 
    //   which is triggered when the user closes the browser window, in that case, we close the WebSocket from 
    //   the client side (as can be seen in the "destroy" function a few linea ahead.
    function sendCloseCommand ( ) {
        websocket.send ( "closeConnection" ); 

        //   Set html buttons state
        buttonStates ( "closedState" );

    }

    //   Closes the WebSocket connection from the client side.
    function closeSocketConnection ( ) {
        websocket.close ( );
    }

    //   We are exiting, close everything.
    function destroy ( ) {
        sendStopCommand       ( );
        closeSocketConnection ( );
    }

As with any HTML5 websocket implementation, we have to cover the lifecycle methods and events, which are:


websocket = new Websocket ( url );
Creates a new connection to the WebSocket represented by url.

websocket.onmessage
Listener that receives incoming messages from the server endpoint.

websocket.onclose
Listener that receives a CLOSE notification when the server closes the connection.

websocket.send
Method that sends messages to the server endpoint. The messages that can be sent by this application are :
  • startMonitor
  • stopMonitor
  • closeConnection
websocket.close
Method to close the connection from the client side.

The different functions have accompanying comments in the code to make it easier to study them.

In this simple application I have defined three different states so we can experiment with the WebSocket lifecycle. The different states change by clicking on the different buttons as shown in the following simplified Finite State Machine diagram:

Simplified Finite State Diagram

 What functionality would you add to this simple example application?


Paragliding to the moon at Puerto de La Cruz, Tenerife
Photo Credit: Paulo Márquez Herrero

PM/pm

No comments:

Post a Comment