Friday, January 11, 2013

WebSockets

The web is based on the request/response paradigm of HTTP.  This pattern comes with inherent latency in communication by forcing a consumer of data to request all data to be consumed.  AJAX has really helped in making web application communication more dynamic than it had been historically; however, all HTTP communication is still completely driven by the client side of the equation.  This forces a developer to engage in user interaction or long-polling to create applications that, while they look and feel dynamic, are really still request/response in some fashion.  Push communication is loosely defined as the ability for a server to send data to its client without requiring the client to ask for it.  People have historically falsified a push application by engaging in long polling solutions.  A long polling solution requires that a client open a connection to the server so the server can keep it open until something is sent to the client.  At that point, the client deals with the data and then opens another long polling connection.  While enabling some dynamism, at the end of the day, it is a hack.  The new WebSocket technology defines an API for creating connections between a web browser and a server.  This allows the web client application to be notified from the server when and if the server has pertinent information for the client.

Walk-through

Following is a sample block of code using Javascript.  This will hit a WebSocket server and handle notifications based on listening to the events from the socket itself.  This sample was stolen verbatim from WebSocket.org and is a great example of a simple creation, connection and consumption mechanism.


var wsUri = "ws://echo.websocket.org/";
  var output;

  function init()
  {
    output = document.getElementById("output");
    testWebSocket();
  }

  function testWebSocket()
  {
    websocket = new WebSocket(wsUri);
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
  }

  function onOpen(evt)
  {
    writeToScreen("CONNECTED");
    doSend("WebSocket rocks");
  }

  function onClose(evt)
  {
    writeToScreen("DISCONNECTED");
  }

  function onMessage(evt)
  {
    writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
    websocket.close();
  }

  function onError(evt)
  {
    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
  }

  function doSend(message)
  {
    writeToScreen("SENT: " + message); 
    websocket.send(message);
  }

  function writeToScreen(message)
  {
    var pre = document.createElement("p");
    pre.style.wordWrap = "break-word";
    pre.innerHTML = message;
    output.appendChild(pre);
  }

  window.addEventListener("load", init, false);
 
You should try to use a WebSocket when you need low latency, real-time connections between the client and the server.  This technology can reduce your application chattiness and provide a truly dynamic experience for all of your users.  As more browsers move to support the WebSocket, this will push the envelope again on developing web based applications.  We will be able to provide the same kind of functionality we have grown used to in a net.tcp environment to distributed users of a web application.