Last year, I was looking into various ways of communication between client and server for one of my project work. Evaluated SignalR too as one of the options. I found decent documentation online to put across a test app to see how it works.
Introduction
SignalR
is a free and open-source software library for Microsoft ASP.NET that provides ability to server-side code push content to the connected clients in real-time.
Pushing data from the server to the client (not just browser clients) has always been a tough problem. SignalR makes it dead easy and handles all the heavy lifting for you.
https://github.com/SignalR/SignalR
Detailed documentation can be found at: https://dotnet.microsoft.com/apps/aspnet/signalr
Most of the shareout online considers it as ASP.NET/Web application solution only which is not true. As mentioned in quote above, client could be a non-browser too like a desktop application.
I gathered that behind the scenes, SignalR
primarily tries to use Web Socket
protocol to send data. WebSocket
is a new HTML5 API (refer my detailed article on it) that enables bi-directional communication between the client and server. In case of any compatibility gap, SignalR uses other protocols like long polling.
P.S.: Since most of the code to make the test app was picked from web, all the credit to them. One specific source that I can recall: https://docs.microsoft.com/en-us/aspnet/signalr/overview/deployment/tutorial-signalr-self-host
Now, a quick peek into the SignalR test app
- Using the SignalR Hub class to setup the server. Defined a hub that exposes a method like an end point for clients to send a message. Server can process the message and send back a response to all or few of the clients.
[HubName("TestHub")]
public class TestHub : Hub
{
public void ProcessMessageFromClient(string message)
{
Console.WriteLine($"<Client sent:> {message}");
// Do some processing with the client request and send the response back
string newMessage = $"<Service sent>: Client message back in upper case: {message.ToUpper()}";
Clients.All.ResponseToClientMessage(newMessage);
}
}
- Specify which “origins” we want to allow our application to accept. It is setup via CORS configuration. CORS is a security concept that allows end points from different domains to interact with each other.
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
- Server is setup using OWIN (Open Web Interface for .NET). OWIN defines an abstraction between .NET web servers and web applications. This helps in self-hosting a web application in a process, outside of IIS.
static void Main(string[] args)
{
string url = @"http://localhost:8080/";
using (WebApp.Start<Startup>(url))
{
Console.WriteLine($"============ SERVER ============");
Console.WriteLine($"Server running at {url}");
Console.WriteLine("Wait for clients message requests for server to respond OR");
Console.WriteLine("Type any message - it will be broadcast to all clients.");
Console.WriteLine($"================================");
// For server broadcast test
// Get hub context
IHubContext ctx = GlobalHost.ConnectionManager.GetHubContext<TestHub>();
string line = null;
while ((line = Console.ReadLine()) != null)
{
string newMessage = $"<Server sent:> {line}";
ctx.Clients.All.MessageFromServer(newMessage);
}
// pause to allow clients to receive
Console.ReadLine();
}
}
In above code, Using IHubContext
:
- Server is setup to have earlier defined Hub as one of the broadcast end point.
- Server is also setup to broadcast any message to all clients by itself if needed be
- Client is setup to communicate with the server (send and receive message) via hub using
HubConnection
&IHubProxy
. Client can invoke the exposed end point in the hub to a send a message.
static void Main(string[] args)
{
string url = @"http://localhost:8080/";
var connection = new HubConnection(url);
IHubProxy _hub = connection.CreateHubProxy("TestHub");
connection.Start().Wait();
// For server side initiation of messages
_hub.On("MessageFromServer", x => Console.WriteLine(x));
_hub.On("ResponseToClientMessage", x => Console.WriteLine(x));
Console.WriteLine($"============ CLIENT ============");
Console.WriteLine("Type any message - it will be sent as a request to server for a response.");
Console.WriteLine($"================================");
string line = null;
while ((line = Console.ReadLine()) != null)
{
// Send message to Server
_hub.Invoke("ProcessMessageFromClient", line).Wait();
}
Console.Read();
}
With above setup, we can see the communication between Client & Server realtime like below:
Things to consider while opting for SignalR
SignalR looks awesome. But, there are couple of things one should know while using it:
- It’s a connected technology – each client connected through
SignalR
is using a persistent and dedicated connection on the Web Server. SignalR is shared as scalable but it never harms to look for any queries around connections, memory, cpu, etc with higher number of clients. - One would need to setup a valid host server with a PORT open on it that can be used for communication. This could depend on an organisation security protocols and approvals.
Hope this gives a quick overview about SignalR. Keep learning!
Download entire code for lookup from here: https://github.com/sandeep-mewara/SignalRTest