How to Push Data from Server to Client Using SignalR

In real-time environments the server is aware of the data updates, event occurrences, etc. but the client doesn’t know it unless the request is initiated by the client to the server seeking the updates. This is commonly achieved through methods like continuous polling, long polling, etc. and these methodologies incur a lot of traffic and load to the server.

The alternate approach to simplify and reduce the overhead is to make the server capable of notifying the clients. There are many technologies introduced to achieve this and some of them are WebSockets, SSE (Server Sent Events), Long polling, etc. Each of these methods has its own caveats like WebSockets are supported only on browsers that support HTML5 and SSE is not supported on Internet Explorer.

SignalR is an Asp.Net library, which is designed to use the existing transport technologies underneath based on the client nature and the support it offers. SignalR is capable of pushing the data to a wide variety of clients such as a Web page, Window application, Window Phone App, etc. The onus is now removed from the developers of worrying about which server push transport to use and deciding on the fallbacks in case of unsupported scenarios.

Composition of SignalR

To start with SignalR it is important to know the components. The server part of the SignalR technology requires hosting a PersistentConnection or a SignalR hub.

1. PersistentConnection – This is a server endpoint to push the messages to the clients. It allows the developers to access the SignalR features at a low level.

2. Hub – It is built on top of the PersistentConnection exposing high-level APIs and it allows the developers to make the server to client calls in an RPC fashion (Remote Procedure Call).

On the client front SignalR offers different client libraries to different clients like Windows App, Web Form, Windows Phone, iOS, Android, etc. The clients have to make use of the client libraries to get connected to the SignalR hub. These client libraries are available as NuGet packages.

Fig 1.0 shows a basic SignalR environment

Basic SignalR Environment
Fig 1.0: Basic SignalR Environment

Sample Application

Let us build a sample chat application that broadcasts the messages to all connected clients or to particular groups. In this example consider the clients to be a Windows application and a web form client.

Creating an Asp.Net SignalR Hub

Open Visual Studio and create an empty Asp.net MVC application named MyChatApplicationServer. Now open the NuGet packages, search and include Microsoft ASP.NET SignalR.

Now right click on the project, add the SignalR Hub class and name it as MyChatHub.  Add the following code to the class.

    public class MyChatHub : Hub
    {
        public void BroadcastMessageToAll(string message)
        {
            Clients.All.newMessageReceived(message);
        }
 
        public void JoinAGroup(string group)
        {
            Groups.Add(Context.ConnectionId, group);
        }
 
        public void RemoveFromAGroup(string group)
        {
            Groups.Remove(Context.ConnectionId, group);
        }
 
        public void BroadcastToGroup(string message, string group)
        {
            Clients.Group(group).newMessageReceived(message);
        }
    }

The HUB class also provides the properties Clients, Groups, Context and events like OnConnected, etc.

Finally you should also add Owin startup class to map the available hubs as shown below.

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

Pushing Data to a Web Form Client

Now create a web form client project named WebClient and add a simple HTML file ChatWebClient.html with the following code. Add the references to the required script files.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="Scripts/jquery-1.6.4.min.js"></script>
    <script src="Scripts/jquery.signalR-2.0.1.min.js"></script>
    <script src="http://localhost:32555/signalr/hubs/" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            var myChatHub = $.connection.myChatHub;
            myChatHub.client.newMessageReceived = function (message) {
                $('#ulChatMessages').append('<li>' + message + '</li>');
            }
            $.connection.hub.url = "http://localhost:32555/signalr";
            $.connection.hub.start().done(function () {
                $('#btnSubmit').click(function (e) {
                    myChatHub.server.broadcastMessageToAll($('#txtEnterMessage').val(), 'Web user');
                });
            }).fail(function (error) {
                console.error(error);
            });;
           
        });
    </script>
</head>
<body>
    <div>
        <label id="lblEnterMessage">Enter Message: </label>
        <input type="text" id="txtEnterMessage" />
        <input type="submit" id="btnSubmit" value="Send Message" />
        <ul id="ulChatMessages"></ul>
    </div>
</body>
</html>

There are two ways of implementing the client function one with proxy and other without. The above example is the one without a proxy.

In the connection start you may also mention which transport SignalR should use.

Pushing Data to a Windows Application Client

Let us add a windows app and subscribe to the SignalR host. Create a new windows application named WinFormClient and from the nugget packages install Microsoft ASP.NET SignalR .NET client package. In the Program.cs add the following code.

namespace WinFormClient
{
    public partial class Form1 : Form
    {
        HubConnection hubConnection;
        IHubProxy hubProxy;
        public Form1()
        {
            InitializeComponent();
            hubConnection = new HubConnection("http://localhost:32555/signalr/hubs");
            hubProxy = hubConnection.CreateHubProxy("MyChatHub");
            hubProxy.On<string>("newMessageReceived", (message) => lstMessages.Items.Add(message));
            hubConnection.Start().Wait();
        }
 
        private void btnSubmit_Click(object sender, EventArgs e)
        {
            hubProxy.Invoke("BroadcastMessageToAll", textBox1.Text, "Window App User").Wait();
        }
    }
}

Once done go ahead and run both the web and Windows client. Enter the messages and look at how the message is getting pushed across both the clients though they are of a different nature. Fig 2.0 shows a sample screenshot.

Web and Windows Clients
Fig 2.0: Web and Windows Clients

SignalR is capable of serving multiple connected clients irrespective of the client platform or technology. I hope this article provides a good amount of information about pushing data from the server to client using Asp.Net SignalR. Happy reading!

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read