Related: "ASP.NET SignalR: More than Just Chat"
In my last column, 4 Great Solutions for Real-Time Communications on the Web, I discussed several common ways that web developers implement real-time communications in their web applications. Although it wasn’t an exhaustive list, it did show that there are several available options. And more importantly, if you decide to implement any of these solutions in your applications, then you’ll also have some work ahead of you.
The problem with each of these four communications models is the fact they all have quirks. They also vary by how widely they are supported in modern browsers. Even if you implement one solution, there’s no guarantee that it will work in all of your user’s browsers. That means that the best solution is to implement all four solutions in your application and include a mechanism that decides on a user-by-user basis on what works best to provide the necessary functionality given the browser model, version, server capabilities, and environment. Fun, right?
Well, yes, as a matter of fact, it would be a fun and interesting project, but it’s not terribly practical or cost effective! Thankfully, Microsoft recognized this need and included features for task-level parallel processing in .NET Framework 4.0. Best of all, Microsoft has also created the open-source project SignalR, which is an asynchronous signaling library for ASP.NET applications.
SignalR provides two programming models you can choose from: persistent connections and hubs.
A persistent connection, using the aptly named PersistentConnection object, supports lower-level socket connections between the client and server to exchange messages. Each client connection to the server is identified by a connectionID. The server has the capability to either communicate with individual clients, broadcast to all the clients, or even selectively communicate with a group of clients.
A persistent connection is the lower-level programming model that’s closer to the reality of the underlying HTTP connection. In fact, it creates a development surface that’s similar to programming with sockets, although here it’s done on the virtual connection established by SignalR. This is how SignalR isolates the application from the transports and complexities inherent to keeping a permanent connection open between the client and the server.
Persistent connections provide everything you need to create real-time multiuser applications through a really simple and intuitive API. Nevertheless, the creators of SignalR have taken it one step further, providing a much higher level of abstraction above web protocols, transports, and persistent connections. That’s where the second SignalR programming model, hubs, comes into play.
Hubs provides a higher level RPC framework rather than a persistent connection. If you have different types of messages that you want to send between server and client, then using hubs is recommended so you don't have to do your own dispatching.
The methods of the proxy objects implement Ajax-style calls to the real methods on the server. Conversely, when the server invokes a method of the client, it’s resolved by using dynamic types and a special protocol that packages these calls at the server and sends them to the other end using the underlying transport.
Usually you’ll want to use hubs when you need to send different types of messages with various structures between the client and server. Persistent connections operate mainly on text strings, which means that you have to parse data manually, which can sometimes be laborious. But with hubs, most of the work is done by the SignalR framework itself, in exchange for a very small additional load.
SignalR supports four communication models, most of which I’ve covered in the last column. These models include WebSockets, server-sent events, long polling, and a variation called forever frames that uses an embedded iframe to manage the client’s side of the communications.
SignalR uses WebSockets if they are available and automatically falls back to other communication models as necessary to fit in with what works with the client browser and environment. That’s the single best part of SignalR: you can let it make the right choice of which technology to use underneath to keep the persistent connection going. That frees you from worrying about the compatibility issues and lets SignalR manage the connections between client and server.
You can find SignalR documentation and sample applications on Microsoft’s SignalR landing page. The canonical example of SignalR is a chat application, and there are plenty of those floating around. Once you get a feel for what SignalR does, then you’ll no doubt find a myriad of uses for this technology. One of the best resources on SignalR that features ideas on how to put it to use is Rick Stahl’s blog in which he explores the technology for his own use.