The Web
Here we are again, back to the dumb client. Our web browsers have served as the passive client for years. The model is frighteningly similar to the terminal solution of the '70s; a dumb client capable of taking input and rendering whatever comes across the network, and a rich server doing all the work.
Hypertext Transfer Protocol (HTTP) is what makes up the Web. It surfaced for the first time in 1991 and basically describes a protocol for making a request to a server and the server sending a response back. The protocol is stateless and you will need to keep the state either on the server or the client. Within the protocol there are well-defined verbs that can be used, such as POST, GET, PUT, DELETE, and many more. These verbs let us describe what we are doing. However, a well-defined and rich protocol has nothing defined in it to let the clients be persistently connected. You can read more about HTTP at http://en.wikipedia.org/wiki/Http.
As the capability of web browsers has increased over time, we've watched them go from being very passive to rich clients. The mid 2000s gave us the buzz often referred to as Web 2.0 and AJAX (Asynchronous JavaScript and XML). At the core of this JavaScript was something called XHR (XMLHttpRequest), making it programmatically possible to call the server from the client without any user interaction. This technique leverages HTTP, and you find yourself getting parts or even the data instead of getting whole web pages. You can put the data into the already-rendered web page. You can find more details about AJAX at http://en.wikipedia.org/wiki/Ajax_(programming).
Modern web applications are turning into a hybrid of rich clients and thin clients; very capable, but they shouldn't do it all – we also need the server-side logic. A true step in the right direction is letting the client be good at its forte and doing likewise with the server, thus separating the concerns of the two tiers.
Now that we have all this power in the browser, we quickly run into similar problems as those we run into with regular rich clients, that is, states on the client.
Full duplex on the Web
With the evolution going back to where we started from, meaning that we are now at a point where we need the same kind of connectivity that we needed for rich desktop applications in the past, but now the demand is that applications go live on the web. With user demand come technical challenges: the web is not built for this; the web is based on a request/response pattern. The browser goes to a specific URL and a server generates a resource.
One of the things that the W3C organization has done to accommodate this need is the standardization of something called WebSocket: full-duplex communication channel over a single TCP connection. A very good initiative is something that will be supported by all browser vendors as well as web servers. The challenge, with it getting a broad adoption, is on the infrastructure that makes up the Web. The entire infrastructure has been optimized for the request/response pattern, and a steady connection establishes a point-to-point connection between two computers, and all of a sudden scalability becomes an issue. So in many cases, this might not be the best solution.
Events
Another initiative called server-sent events was implemented by Opera, the Norwegian browser vendor, which is now being standardized by W3C. It gives us the opportunity to push events from the server to the clients that are connected. On combining it with the regular HTTP request/response, we are able to meet the requirements of rich applications. You can read more about server-sent events at http://en.wikipedia.org/wiki/Server-sent_events.
Comet
Not changing the subject just yet, a technique called Comet has also been applied with great success. The basic principle is to utilize something called long polling HTTP requests. One opens an HTTP request to the server from the client, and the server does not return anything until it has something to return, like an event that happens on the server. When the response has been given, the client starts a new long polling connection and keeps on doing so for ever. This simulates a full-duplex connection and scales very well with the existing infrastructure of the Web, as shown in the following block diagram. You can read more about comet here: http://en.wikipedia.org/wiki/Comet_(programming).
Hand-rolling it all
By now you probably know where I am going with this. The techniques described previously are some of the techniques that SignalR utilizes. The techniques and standards are well known, and nothing is holding you back from working with them directly, but this is where SignalR comes in and saves the day.
Why?
The most important thing to ask in software development is "why?" (http://en.wikipedia.org/wiki/5_Whys). Why do we want all this? What is it that we're really trying to solve? We're trying to make the software more collaborative and make users work together without having artificial technical limitations to this collaboration. In fact, why not have the changes occur in real time when all the users are collaborating?
Now what?
SignalR represents an abstraction for all the techniques that it supports today, and with it we also gain the extensibility of supporting techniques that might come along in the future. It has a built-in fallback mechanism which enables it to pick the best solution for your app and its environment, and it is also based on the client connection. In addition, SignalR provides great mechanisms for scaling out in a multiserver environment, enabling applications to be blissfully unaware of the server they are running on and just work with the same abstraction as if it was only one server.
Think different
Apple coined the phrase Think different back in 1997. The phrase in itself forces you to think differently, since it is grammatically incorrect. With all the asynchronous operations and events going into a technology like SignalR, one really has to think in a different manner, but a manner that is different in a good way. It is good for users, as we are now forced to create user experiences that are non-blocking. Of course, you as a developer can force locks onto the users, but I would argue that it would be easier not to, and instead approach building the user interface in a different manner.
For instance, one of the things that we tend to build into our apps is the notion of concurrency and stale data. We don't want to run the risk of two users updating the exact same data and one client not having the updated data from the other user. Often we leave our users to get a bizarre error message that the user often won't understand. A better solution would be to have all the data on all user screens be updated as they are looking at it, and maybe even make them aware in a subtle way of the changes that happened due to the other user(s).
Personal style
Throughout this book, you'll run into things you might disagree with. It could be things in naming the classes or methods in C#, for instance, at times, I like to drop camel casing, both upper and lower, and just separate the words with underscores yielding "some_type_with_spaces". In addition, I don't use modifiers without them adding any value. You'll see that I completely avoid private as that is the default modifier for fields or properties on types. I'll also avoid things such as read-only, especially if it's a private member. Most annoyingly, you might see that I drop scoping for single line statements following an IF or FOR. Don't worry, this is my personal style; you can do as you please. All I'm asking is that you don't judge me by how my code looks. I'm not a huge fan of measuring code quality with tools such as R# and its default setting for squiggles. In fact, a colleague and I have been toying with the idea of using the underscore trick for all our code, as it really makes it a lot easier to read.
You'll notice throughout that I'm using built-in functions in the browser in JavaScript, where you might expect jQuery. The reason for this is basically that I try to limit the usage of jQuery. In fact, it's a dependency I'd prefer not to have in my solutions, as it does not add anything to the way I do things. There is a bit of an educational, also quite intentional, reason for me to not use jQuery as well: we now have most of the things we need in the browser already.