HTML5 WebSockets

One of the most exiting new things in HTML5 is the ability to start pushing data from the server to the client. Traditionally web applications have depended on clients requesting data from the server. And this is fine in most applications. However there are lots of cases when you might want to push events to the client as soon as they happen and not wait for a client to query for them. For example a stock broker application requires traders to know about stock price changes as soon as they happen, alerting the trader 5 minutes after the fact is no good.

Traditionally this could be done using long polling. This technique can be quite effective but a bit troublesome in getting to work reliably. The long polling mechanism has actually been formalized in the HTML5 specs as well with Server-sent DOM events and the the EventSource object. While quite effective, and relatively well supported, there is a newer technique of WebSockets that is far more capable.

 

No more HTTP traffic

The WebSockets standard has one slight drawback though in that is is no longer using HTTP traffic. Where the EventSource object uses standard HTTP traffic and has no special requirements on the server the same isn’t true for WebSockets. With WebSockets the initial request starts of as an HTTP request but after that it upgrades to the WS protocol. Or in the case of a secure WebSocket connection we can use the WSS protocol that provides for a secure communication just like HTTPS does.

This new WS and WSS protocol does mean we need some additional capabilities on the server. Depending on your technology choices you can use any number of libraries. The most popular server side implementation seems to be Socket.IO which is a Node.js based implementation. As I am a .NET developer I tend to go for a .NET library. There are different implementations, for example in WCF 4.5 or in SignalR however both of these are dependent on Windows Server 8. There is another library I tend to use at the moment called Fleck which works well but unfortunately doesn’t want to share port 80 meaning that I can’t run a live example on my shared hosted site.

The required server side code for a simple chat application with Fleck is real simple:

var connections = new List<IWebSocketConnection>();


var host = System.Web.HttpContext.Current.Request.Url.Host;


var ws = new WebSocketServer("ws://" + host + ":81/chat");


 


ws.Start(conn =>


{


    conn.OnOpen = () =>


    {


        connections.Add(conn);


    };


 


    conn.OnMessage = s =>


    {


        foreach (var item in connections)


        {


            item.Send(s);


        }


    };


    conn.OnClose = () =>


    {


        connections.Remove(conn);


    };


 


    conn.OnError = s => {


    };


});

 

The client side code is also real simple.

$(function () {


     var ws = new WebSocket('ws://' + location.hostname + ':81/chat');


     ws.onopen = function () {


         <li>').text('Connection open').prependTo('#messages');


     };


     ws.onmessage = function (e) {


         $('<li>').text(e.data).prependTo('#messages');


     };


     ws.onerror = function (e) {


         $('<li>').text('Connection error').prependTo('#messages');


     };


 


     $('#btn').click(function () {


         var txt = $('#txt').val();


         ws.send(txt);


         $('#txt').val('').focus();


     });


 });



Basically all we need to do is create a WebSocket object with the required URL and start listening for messages using the onmessage callback. Every time a message is received the eventArgs.data contain the actual message data being send. If we want to send data to the server we can also use the same WebSocket connection as this is fully duplex. All we need to to is use the send method specifying the data we want to send.



 



Messages



In the chat example all data being passed are just simple strings but this is no requirement. In fact if we want to send more complex data we can send it as binary data, no need to base64 encode it first.



 



Conclusion



I am exited about a lot of material in the new HTML5 standard but WebSockets and real time communication is extra exiting. it is going to enable a whole series of applications that where very hard, or even impossible, to write in a scalable way. And that is not just chat applications or tock trading but lots of others.



The main problem right now is the lack of widespread support for the WebSocket standard. In fact only FireFox and Chrome have good support and IE is getting it in version 10. But fortunately libraries like SignalR make a lot of the same possible with fallbacks to more traditional communication mechanisms when WebSockets aren’t supported by the client and the server. Stay tuned for more on SignalR in a future post.



 



Enjoy!

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>