SignalR – Introduction to SignalR – Quick Chat App
This article is an introduction to a series I will be publishing over the next few weeks. All based on SignalR and common scenarios when utilising this awesome library in web development.
What is SignalR
SignalR is an open source async signalling library. It was made by David Fowler and Damian Edwards.
In a nutshell, it allows you to pass data between client and server in realtime. It’s not only for web, it has JS, .Net, WP7 and Silverlight clients and supports self-hosting so you can run the SignalR server in win service or web context. It will run on .Net 4.0 or 4.5 and to get websockets running, you will need IIS8 or IIS8 Express. That said, it will run on older versions of IIS and will switch to different transport modes.
Hubs and Persistent Connections
SignalR talks about two concepts – persistent connections and hubs. Persistent Connection is a lower level API which is exposed over http. Hubs expose public methods to the clients and raise callbacks on the clients. In most web-based scenarios, you will be utilising hubs, which follow the publish-subscribe pattern.
Transport Modes Available
When a connection between a web client and a server is made, SignalR will determine a suitable transport type based on your client capabilities. It will gracefully degrade so older browsers might get long-polling instead of the fancy websockets. The transport mode can have a significant impact on the performance of the app.
- WebSockets (bidirectional stream)
- Server Sent Events (push notifications from server to browser using DOM events)
- Forever Frame (uses HTTP 1.1 chunked encoding to establish a single long-lived HTTP connection in a hidden iframe)
- Long polling (hit the server hit the server hit the server hit the server hit server and hope something comes back with data)
Creating your first hub
First, you will need to include SignalR in your project. The quickest way is to use NuGet. You will notice, there are various packages available. In this example, we are using both client and server parts of SignalR –> therefore you should choose the very first “SignalR” option. This will bring down all the dependencies.
Creating a new hub then becomes very easy. Simply create a class and inherit from an abstract Hub class.
1public class ChatHub : Hub
2{
3 //your code here ...
4}
Connecting to the Hub from a web client
In order to connect to the hub, you will need to add couple of Javascript references. Please note that SignalR uses JQuery. Therefore if it’s not included already, you should include it before initialising signalR.
1....
2 <script type="text/javascript" src="~/Scripts/jquery.signalR-0.5.3.js"></script>
3 <script type="text/javascript" src="~/signalr/hubs"></script>
4....
The ~/signalr/hubs endpoint exposes all the available hubs in the solution and lets you access their public methods. You will first need to initiate connection.
1$.connection.hub.start()
2 .done(function() {
3 console.log("Connected!");
4 })
5 .fail(function() {
6 console.log("Could not Connect!");
7 });
Distributing your messages to the clients
Once you have made a connection to the hub, your client can then call the public methods on the hub and subscribe to the callbacks received from the hub.
1public class ChatHub : Hub
2{
3 private readonly IRepository _repository;
4
5 public ChatHub(IRepository repository)
6 {
7 _repository = repository;
8 }
9
10 public void Send(string message)
11 {
12 var msg = new ChatMessage() {Message = message};
13 _repository.Save(msg);
14
15 Clients.receiveChat(msg);
16 }
17}
When you want to distribute messages to your clients, you can do so using the Clients dynamic object. Any method that you call on Clients will raise a callback on the client. Furthermore, you can get access to the current client call id using Context.ConnectionId or Groups dynamic object which looks after groups management. To publish on a specific connection you can you Clients[“gropuName”].method(params) or Clients[Context.ConnectionId].method(params).
Finally, you should register your client callbacks in JS and wire-up the buttons, fields and your preferred rendering template
1var chatHub = undefined;
2
3var init = function () {
4 $(".chat-submit").on("click", sendMessage);
5
6 chatHub = $.connection.chatHub;
7
8 chatHub.receiveChat = function (value) {
9 console.log('Server called addMessage(' + value + ')');
10 $("ul.chat-list").prepend($(".chat-template").render(value));
11 $("ul.chat-list li:gt(2)").remove();
12 };
13};
14
15var sendMessage = function() {
16 chatHub.send($(".chat-message").val());
17};
And that’s it, simple as that. You can check out the code sample below (it is a part of a bigger project and there is much more to come). Any questions, give me a shout @mirajavora
Related Links
Download the code
The sample app is based on MVC4 with Castle Windsor DI and FluentNhibernate. You can edit the connection string in web.config and run /boot to get the schema created.
Related Articles
SignalR – Introduction To SignalR SignalR – Publish Data Using IHubContext SignalR – Publish Data Using Proxies SignalR – Dependency Injection