You want to write software that works just like popular social networking sites do, with lively, immediate information. That means building real-time high-frequency updates into your software, because users want their data and they want it now. In some situations, moving data in real-time is essential to the success of the app as it gives an upper hand to the business that does so. Not just that, but let's face it - it's cool to be the developer who writes the high tech websites. If you want to build these modern websites and apps with live, two-way communication, then SignalR is something you should seriously consider.
What is SignalR and why should you use it?
SignalR is a set of libraries that facilitate easy development of these kind of real-time websites and apps. It is open source, and you can get it here: GitHub. It works across all the major platforms. SignalR the newest member of the ASP.NET family, that enables developers to write incredibly simple real-time, two-way websites and apps. Two-way communication means that both the server and client share an open channel in which they can initiate contact with each other. This channel is high-speed and works both directions between server and client. Many kinds of software can benefit from the real-time, two-way, communication system of SignalR. They include high traffic finance and stock apps, auctions, voting, quizzes and polls, lotteries, games, and many more. If your app's not in the list, you still might want to investigate Signal, as UXs with high-frequency updates tend to be the ones that the users prefer (and rate higher for those in app stores).
SignalR is built to the OWIN specification. OWIN, short for Open Web Interface for .NET, is a set of standards for constructing a pluggable, modular, Web server architectures. Fortunately as SignalR developers, we don't really need to dig into the specs to write SignalR code, most of the time.
Conceptually, SignalR works like a hub and spoke, or hubs and clients, as we call them. This means that the client can call the server, like we normally see in a HTTP Request-Response model, but now the server can contact the client, and one client can contact other clients (through the server). This is not the kind of programming that web developers usually do. SignalR contains two primary components: Hubs and Clients. Hubs, as you might expect, are server side and they behave a lot like super fast switchboard operators (oxymoron?). Clients, on the other hand, behave the same, except that now they can also receive calls from the server. This is where SignalR differs from customary Web programming, in that both sides can initiate communications between each other once the client initially opens the pipeline.
SignalR uses Websockets technology everywhere that it possibly can, and when it's not possible, it uses an algorithm to determine the best possible transport. It supports the following transports: WebSockets, Long Polling, Server Side Events, and Forever Frame. As developers, we barely need to know cursory information about these frameworks to benefit from SignalR.
Get Started With SignalR Development
Since SignalR is an ASP.NET product, we'll need to create an ASP.NET project in Visual Studio (unless you self-host, but we'll stick with ASP.NET here). You can go with either Web Forms or MVC, as SignalR is also ASP.NET, and it all works together. Then install the "Microsoft ASP.NET SignalR" package into the ASP.NET project, using either the GUI or the Package Manager console. When you install the generic "Microsoft ASP.NET SignalR" package, it installs a few dependencies. Those are both server and client side components that work in tandem so that SignalR can do its thing. You can verify the installation by checking for references to Owin under the project references and jquery.signalr-2.0.3.js and similar files under the Scripts node in Solution Explorer.
Every site needs a starting point, and for SignalR apps, we need to hook into the OWIN pipeline of modular architecture. That means that we need to run a quick bit of code during startup. To do so, put the following code in a class in App_Start. This tells ASP.NET that the SignalR OWIN modules will be part of the regular IIS pipeline. Below is sample startup code for a voting app. The app loads several images and allows users to vote on one or more items.
Once we insert the startup code, we can move to our centerpiece of activity, the hub.
Hubs enable developers to write code to accept calls from clients and call methods on clients. When many people are voting, the action happen incredibly fast, so it's a perfect candidate for real-time connectivity. Not to mention that users want to see the vote total updating in real time. Let's see this in action by examining the VoteHub class. The VoteHub class inherits from the Microsoft.AspNet.SignalR namespace. In this class is the Vote public method that that the clients can call, and when they do, it is syntactically similar to an ASMX Web Service call, meaning that it uses standard dot notation (see the Clients section of this post). The private AddVote method is just a method that public or other private methods call. It accesses some static members to track which client has the highest bid.
Any custom public method (not overrides) in that you add to your Hub class is callable via dot notation from the client, via a special property. Notice that in the above code sample that there is no need to write code to deal with concurrency or transport negotiation, SignalR does it all for you.
With script, we first must obtain a connection to the VoteHub and store it in the voteHub variable. Notice the syntax , $.connection, is a static reference. This is a proxy that SignalR automatically creates for us at the /signalr/hubs location. You need do nothing special for the proxy to work.
After obtaining a connection to the hub, we must start the hub if it isn't already started. This is a good time to wire up any events such as click events where you'll be calling hub methods. After wiring up calls to the hub, it's time to declare methods that the server will call. In the example below, these methods are voteHub.client.joinVoting and voteHub.client.updateVoteResults. Notice their declaration uses the hub.client.method syntax, hanging the methods off of the client property of the reference to the hub. To call code on the server, just use the server property of the client side hub object. In this case, that is voteHub.server.vote. The code passes the value of this.id to the method. "This", in this case is the button containing the ID of the item the user is voting for.
When a new user connects, the OnConnected method in the Hubs example calls the client side joinvoting and passes in voting history. This way the new voter is current, as joinVoting also displays all the information about all the votes in progress. Examining either the voteHub object or Hub class, you'll see the server and Clients properties. These are the properties that enable the two-way real-time communication between the hub and the client. All you do is attach public methods to them and make the calls using the hub.server.method syntax. Finally The updateVoteResults method does the UI update, so each item's <span> element displays how many votes it has.
There are many kinds of websites and apps that can benefit from SignalR's real-time, two-way, communications model. Perhaps a stockbroker needs financial information to buy the right stock at the right time and get a promotion. Or maybe someone is building the next big thing in social networking and the "likes" need to happen right away. That high-action game that everyone is addicted to needs to be in real-time or people wouldn't enjoy it as much. If it's an app, enjoyment and a rich experience translate directly to ratings, which in turn translates to more visibility and revenue.
While in this article I've only mentioned Hubs and clients, there is lower level of abstraction that SignalR offers called a Persistent Connection. If you, for whatever reason, need to perform more of the lower level tasks regarding connection management, the PersistentConnection class is what you'd use. If you check out the members of the PersistentConnection class, they look a lot like the Hub class but with more members regarding connectivity. It gives you more granular control, but for most scenarios, hubs and clients will work just fine.
Download sample code: https://github.com/rachelappel/VoteR