SignalR

Is a framework that we can use to easily manage the communication between different clients (e.g. for creating a chat). It defines the concept of hub, that is the central point towards which each client is connected. With SignalR we can share information between every client connected to the same hub. It uses OWIN (Open Web Interface for .Net) in order to work. SignalR uses different technologies to pursue its purpose: depending on the browser’s capabilities it can use web sockets or polling, with all the available optimizations.

First of all we have to add SIgnalR to our MVC Framework website. This can be done via NuGet:

Then we can add SignalR to an OWIN startup class to map it on the app builder pipeline. To do this we can create a class (in this example on the website root) in the following way:

using Microsoft.Owin;
using Owin;
 
[assembly: OwinStartup(typeof(ProvaSignalR.Startup))]
namespace ProvaSignalR
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Now we can create our SignalR hub. A very interesting thing about hubs is that every method defined within them will be available on client side (through the server object of the client-side proxy auto-generated from its class). At the same way we can invoke any client-side method defined within the client object of the same proxy. With this hub we are telling that every time some client invoke our Send() method to post a new message, we have to broadcast the same message to all the clients, by calling their addNewMessageToPage() client-side method.

namespace ProvaSignalR.Hubs
{
    public class ChatHub : Hub
    {
        //Every method in this class will be
        //available for calling on client-side
        public void Send(string name, string message)
        {
            //We can call methods that are defined on client-side.
            //In this case we are calling the client-side method
            //addNewMessageToPage() for all the hub's clients
            Clients.All.addNewMessageToPage(name, message);
        }
    }
}

Finally, to test our chat, we can create a new action (e.g. “Chat”) with this related view:

@{
    ViewBag.Title = "Chat";
}
 
<h2>Chat</h2><div class="container">
    <input type="text" id="message" />
    <input type="button" id="sendmessage" value="Send" />
    <input type="hidden" id="displayname" />
    <ul id="discussion"></ul>
</div>
 
@section scripts {
    <script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
 
    <!--
        This is the autogenerated SignalR hub script. It defines
        the proxy that we will use to communicate with the server
    -->
    <script src="~/signalr/hubs"></script>
 
    <script>
        $(function () {
 
            //Ask for the client name
            $('#displayname').val(prompt('Enter your name:', ''));
            $('#message').focus();
 
            //Create a reference to the hub proxy
            var chat = $.connection.chatHub;
 
            //Every method defined within the
            //client object of the proxy will be
            //available for calling on server-side
            chat.client.addNewMessageToPage = function (name, message) {
                $('#discussion').append('<li><strong>' + htmlEncode(name)
                    + '</strong>: ' + htmlEncode(message) + '</li>');
            };
 
            //Start the connection with the hub
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
 
                    //We can call methods that are defined on
                    //server-side. In this case we are calling the
                    //server-side method Send() for the referenced hub
                    chat.server.send($('#displayname').val(), $('#message').val());
                    $('#message').val('').focus();
                });
            });
        });
 
        //This optional function html-encodes
        //messages for display in the page
        function htmlEncode(value) {
            var encodedValue = $('<div />').text(value).html();
            return encodedValue;
        }
    </script>
}