The Problem Solver

Tell me and I will forget
Show me and I will remember
Involve me and I will understand
- Confucius -

Google Ads

This Blog

Syndication

Search

Tags

News





  • View Maurice De Beijer's profile on LinkedIn

Community

Email Notifications

Explore

Archives

July 2012 - Posts

In a previous post I showed how easy it is to create a simple chat application using SignalR. And chatting on the internet might be popular but as it turns out there are rather a lot of applications that need to do more than just chat. As it is there are a lot more CRUD style applications, where users edit data usually stored in a database for some purpose, than chat applications. So in this blog post I am using a simple CRUD, without the delete part, application to show the power of SignalR.

Traditionally HTML based CRUD would generate all HTML on the server based on the user selecting something and then using an HTML form and an HTTP POST to send the changes back to the server. The newer generation of applications might just send the HTML skeleton to the client and some client side JavaScript would run, load the data and display it to the user. Updates would be done in a similar fashion with some JavaScript. To be fair the JavaScript would be using jQuery in most cases and would be quite trivial to write against some REST service.

However both these approaches have one fundamental problem. When a user requests some data he has a local copy of that in the browser. If another user now updates that same entity on the server the first user still has the old stale data in front of him. And that will remain so until reloads the data. Of course we can add some code to actively check for changes to the data but usually there will be no change so that results in a lot of useless network traffic.

 

Replacing a REST service with SignalR

Suppose the client doesn’t load the data using a REST service but uses SignalR instead. Doing request/response asynchronous style communication with SignalR is easy, a little different from using jQuery but no big difference. In the following code the clients starts the communications hub and passed the loadBooks callback to load the books as soon as the communications are initialized.

$(function () {
    var hub = $.connection.booksHub;
    $.connection.hub.start(loadBooks);
    $("#load").click(loadBooks);
 
    function loadBooks() {
        hub.getBooks().then(function (books) {
            var ul = $("#books");
            ul.empty();
            $.each(books, function () {
                var newLi = $("<li>").appendTo(ul);
                renderBook(newLi, this);
            });
        });
    };
 
    function renderBook(li, book) {
        $(li).text(book.Title + " by " + book.Author)
            .attr("data-id", book.Id)
            .data("title", book.Title)
            .data("author", book.Author);
    }
}

 

The C# code on the server is no big deal either and hardly any more complex then the previous chat application.

public class BooksHub : Hub
{
    private IBooksRepository _repo = new BooksRepository();
 
    public IEnumerable<Book> GetBooks()
    {
        var books = _repo.GetBooks();
        return books;
    }
}

 

Push notifications after updates

So far we have not achieved much, the user will still be looking at stale data when the data on the server is updated by another user. But SignalR uses persistent connections and can easily push changes to each connected client when that happens. All we need to do is add a bit of client side code to send updates and handle the change notifications.

 

$("#updateBook").submit(function (e) {
    e.preventDefault();
    var form = $(this);
 
    var book = {
        id: $("#id", form).val(),
        title: $("#title", form).val(),
        author: $("#author", form).val()
    };
    hub.updateBook(book);
});
 
hub.bookUpdated = function (book) {
    var form = $("#updateBook");
    form.slideUp();
    var li = $("li[data-id=" + book.Id + "]");
    if (li.length === 0) {
        var li = $("<li>").appendTo("#books");
    }
    renderBook(li.get(0), book);
    li.animate({ "background-color": "Yellow" }, 500, function () {
        li.css("background-color", "")
    });
}

 

The first method sends changes to the server, this is pretty basic clients side JavaScript code. The second bookUpdated function is called whenever the server broadcasts a change to all clients. This function first tries to locate the updated book and to update it on screen. If the book isn’t found it adds it to the bottom of the list.

 

Supporting this on the server using a SignalR hub is easy. Below is the complete C# source code for the hub that servers up data, accepts updates and inserts and broadcasts those updates and inserts to all connected clients.

public class BooksHub : Hub
{
    private IBooksRepository _repo = new BooksRepository();
 
    public IEnumerable<Book> GetBooks()
    {
        var books = _repo.GetBooks();
        return books;
    }
 
    public void updateBook(Book book)
    {
        var newBook = _repo.UpdateBook(book);
        this.Clients.bookUpdated(newBook);
    }
 
    public void addBook(Book book)
    {
        var newBook = _repo.AddBook(book);
        this.Clients.bookUpdated(newBook);
    }
}

 

With this addition each user is automatically notified of any change anyone makes and will see the data in the browser update dynamically. For some extra effects I have added a small jQuery animation to the record being updated on the client.

 

Want to try?

If you want to try this I have a live demo on my site where you can test this SignalR style page. Make sure to open the page in multiple browsers, click on a book and hit Save. You will see the change simultaneous in each browser.

 

Conclusion

I think doing push updates like this will become more and more popular over the next year. just imagine the power of updating websites real time when people are browsing, not when they refresh but as they read. Maybe Amazon would do something like detect you are staying on the same book page and decided to drop the page and animate the effect while you are reading. Sounds like a nice way to get a few percent extra sales right?

 

Enjoy!

Posted by Maurice | with no comments
Filed under: , , ,

One of the easy ways of speeding up a web application is by using a CDN or content delivery network. The main purpose of a CDN is serving up resources that are not specific to you site.

The quintessential example of using a CDN is jQuery. There are many websites using jQuery, according to some statistics some 50% of all websites. And if each site hosts its own copy of jQuery everyone has to download it multiple times. How often depends but assuming everyone does a perfect job of adding cache settings and browsers have plenty of space to cache things jQuery is going to be downloaded once for each website.

Seems like a waste right?

Yes it is, if everyone is using the same version of jQuery it is much more efficient to download it once from a common place and sharing that cached version. And that is one of the main points of a CDN.

 

There is more though

The caching behavior is the most important but there is more to using a CDN. It turns out there is a limited number of concurrent requests a browser will do to a given domain. If you exceed this number of requests additional ones will be put in a queue until one of the current requests is finished. Splitting up these requests over different domains means you can do more concurrent requests.

Another benefit is that the CDN, being a different domain, isn’t burdened with cookies ties to your websites domain. You should not over use cookies but it’s still a useful optimization.

But the first one, caching is the most important because it will mean that a resource doesn’t need to be downloaded in the first place.

 

Choosing a CDN

It seems easy to choose a CDN, just find the fastest one and use that. And you see a lot of speed comparisons between CDN’s doing just that. While the speed is important that is slightly misleading though. The fact that a resource is already cached when you need it is far more important. So a CDN that is popular and used a lot of even more important that it’s raw speed.

There are several big players in the CDN marketplace including Microsoft and Google. Assuming we want to use a CDN for jQuery we can use either of those or use the jQuery CDN as well.

All these three point to the same version of jQuery. However as the Google CDN seems to be the most popular one that seems to be the best to use.

 

It isn’t just goodness

One thing to be aware of is that you are now taking a dependency on a external system. And while these are quite reliable you should add some code to provide for the service not working as you would like. If you look at the source of one of my HTML5 websites you will see the code I use for that purpose. First I link to jQuery on the Google CDN. If for some reason that fails the script block below detects that jQuery doesn’t exists yet by checking window.jQuery and it it isn’t defined it dynamically inserts a script element downloading from my own server.

 

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
   1:  
   2: <script>window.jQuery || document.write(unescape("%3Cscript src='/Scripts/jquery-1.7.2.min.js'%3E%3C/script%3E"));
</script>

 

There are different ways of doing this, for example using a conditional resource loader like YepNope.js but this is one easy way of doing so without external dependencies.

 

During a recent trip to China I discovered a problem with using the Google CDN that is not apparent in Europe or the USA. Downloading the Google copy of jQuery actually took over 4 seconds, not good and much slower than the other resources downloaded from my own domain. So be very aware of the speed of the CDN for all your customers, it might vary greatly depending on the users location. If you want to be really optimized you will need to determine the users location based on their IP address and server up files using different CDN’s, or your own server, depending on location.

 

Enjoy!

Posted by Maurice | with no comments
Filed under: , ,

In deze podcast spreekt Hassan Fadili met Peter Provost over unit testen. Peter Provost is een senior program manager voor Microsoft Visual Studio waar hij aan de agile tools werkt. Tijdens Tech-Ed Europe was hij in Amsterdam voor diverse sessies over TDD en Agile development.

Links:

Met dank aan onze sponsor RedGate.

 

Enjoy!

Posted by Maurice | with no comments

In a previous blog post I mentioned how exited I was about WebSockets and the future with real time duplex communication over the Internet. Unfortunately the current support for WebSockets, both on the client and on the server, is still somewhat limited making this a thing of the future. Does that mean we can do this yet? Not quite.

 

SignalR to the resque

Even if a pure Web Socket solution isn’t possible yet there are perfectly good alternatives. And the one I really like is SignalR as it allows for the same kind of application today. Check out a live demo of a simple chat application here.

So if SignalR works today does it mean it doesn’t use Web Sockets? Well it might or might not depending on the circumstances. SignalR actually provides an abstraction layer over the actual transport used. And depending on the client and sever capabilities it can use one or 4 different networking techniques

  • WebSockets
  • Server Send Events
  • Forever frame
  • Long polling

It just chooses the best solution that both the browser and server support.

 

SignalR is multi browser

I have create a simple chat page using SignalR and as you can see in the screenshot below it supports lots of browsers on different platforms, here I used desktop IE, Chrome and FireFox as wel as my iPad and Windows Phone 7. All of these just work with SignalR. Pretty good as Web Sockets would only work on Chrome and FireFox at the moment.

image

 

The client side code

The HTML markup required is really simple

<h2>
    SignalR Chat</h2>
<input type="text" id="txt" />
<button id="btn">
    Submit</button>
<ul id='messages'>
</ul>
 
<script src='@Url.Content("~/Scripts/jquery.signalR-0.5.2.js")'>
   1:  
</script>
   1:  
   2:  
   3: <script src='@Url.Content("~/signalr/hubs")/'> 
</script>
 
The most important thing about the markup is the two script references at the bottom. The firsts, jquery.signalR-0.5.2.js, points to client side library that ships with SignalR. The second, /signalr/hubs, is a dynamically generated based on the server side Hub classes, see below.
 
The client side JavaScript is also quite simple.
 
$(function () {
    var hub = $.connection.signalRChatHub;
    $.connection.hub.start();
 
    hub.ChatMessage = function (msg) {
        $('<li>').text(msg).prependTo('#messages');
    };
 
    $('#btn').click(function () {
        var txt = $('#txt').val();
        hub.sendMessage(txt);
        $('#txt').val('').focus();
    });
});
 
Basically SignalR extends jQuery and add the connection property containing a property for each hub. Next we call start() to initialize the communication and start listening for the ChatMessage callback, this is the method being called on the server Clients property below. To send some data to the server we just call the sendMessage() function, the public function defined on the server side hub below.
 
 

The server parts

The server side implementation of SignalR is also quite nice. All I had to do is add the SignalR nuget package and create a class deriving from Hub.

public class SignalRChatHub : Hub
{
    public void SendMessage(string message)
    {
        Clients.ChatMessage("Echo " + message);
    }
}

The public SendMessage is automatically made available to JavaScript clients and the Clients property is a Dynamic object. Just call a method on Clients and it will fire on all connected JavaScript client. You can also just call back to the originating client using the Dynamic Caller property if you want to. And best of all this works perfectly fine with my budget shared hosing account.

 

Check out a live demo here.

 

 

Enjoy!

Posted by Maurice | 1 comment(s)
Filed under: , , , ,

In deze podcast spreekt Maurice de Beijer met Wouter van Vugt over hoe hij SharePoint inzet bij grote projecten. Wouter verteld hou hij SharePoint niet alleen voor de interne automatisering inzet maar ook voor de publieke pagina’s en de gepersonaliseerde pagina’s waar klanten op inloggen. Hij verteld ook over zijn ervaring met het integreren met DigiD.

 

Luister of download de podcast hier.

 

Met dank aan onze sponsor RedGate.

 

Enjoy!

Posted by Maurice | with no comments
Filed under: , ,

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!

Posted by Maurice | with no comments
Filed under: , , ,