So here we go we the second part about using SignalR where I’m going to show you a practical example on how to build a SignalR based chat system, how to build the client and how to build the server. In case you missed the first part about SignalR and want to discover more on what is happening on a lower level please check my previous article SignalR: What is happening under the hood (Part 1).
The code is available on GitHub and the solution currently contains two projects, one for the client implementation and one for the server implementation. Later, I plan to add another project here for the self-hosted server and we’ll use the same client but this time using this server.
Why I decided to make showcase of SignalR chat system when there are plenty of those out there
Yes It’s true, there are many samples and blog articles out there on how to build a SignalR application/system, but everyone of those was build in ways that I consider is not good for a showcase and the code might be more confusing for someone that is starting with this technology.
The first thing I didn’t like was that the severs and the clients were build under one project, and that is something that might cause unnecessary complexity in the learning process. I prefer to have the client and the server in separate project so we’ll have a clear image on what is needed for the server to work and what is needed for the client.
Creating your ASP.NET Web API project
For the server we are going to use ASP.NET Web API project, we don’t really need to create if we are using only SignalR, but in the real world this is one of the expected situation where we need to incorporate SignalR. So let’s create the server. We are going to use Visual Studio 2015 for this sample.
First we need to create new project that will be ASP.NET Web Application
Let’s name our server project “SignalRChatSystem“, maybe this is not the best name that we could use but let’s go with that since this is not the objective of this post. Click “OK” and select the Web API Template.
Now we have a Web API project with basic functionalities and infrastructure. The next thing we need to add in order to use SignalR is to add SignalR library via Nuget. So open the console and run this command in the Nuget console.
That will install a number of dependencies that are needed for running SignalR on your server. We have now everything we need for basic usage of SignalR, but in order for SignalR to run we need to configure some OWIN/Katana middle wear. In your Startup class (that is in the same namespace as the root of the app) we need to map SignalR and to do that we need this line of code
Creating a SignalR hub
So now we need something that the clients will connect to, in the previous article I mentioned hubs and their general purpose. What I usually do is create Hubs folder where I’m putting all of the hubs that I’ll create.
In this folder I’m going to add new class and select the hub template that is under
Web->SignalR and name it MessagesHub
This template will create sample hub for us
When some client invokes this hub Hello method, the hub will invoke the hello() method of all attached clients. As you can see the hub doesn’t receives any input data and it’s not sending any to the clients, so we want to extend that. Some basic data for a sample chat would be the alias of the client and the message they are sending to the group. Then we’ll do some formatting of the message and send that message to all connected clients.
Auto-generated Hubs Java Script proxy
If we start out Web API service project the default page from the template will be open. But when we build the project a java script proxy for our hubs is created. This proxy is useful to use when building the client and the code is a little bit more clear and clean.
If you want to check the generated proxy you can open the url ~/signalr/hubs in your service project. In my case the url is http://localhost:62154/signalr/hubs.
Creating the chat client
As I mentioned at the beginning of this post, my purpose was to create a very simple client in a separate project without using Angular, Knockout or any other not needed framework for building a sample and demonstrating how a SignalR build chat system works.
For those reasons we’ll add empty web project, we’ll add one simple html page, one JS file for writing the SignalR communication logic to the server and we’ll add few dependencies. And that’s it.
PM> Install-Package Microsoft.AspNet.SignalR
One other dependency that we need to add here is jQuery.
PM> Install-Package jQuery
After we add the index.html page we are going to add just few basic fields that are needed for a chat application and we are not going to bother much about the design. Basically we want to build this appearance:
Just note that we need to add some dependencies here
As you can see beside jQuery and SignalR there is reference to chatClient.js which is our custom build file where we are implementing the SignalR communication with the server and the defining what is happening with the message we are sending back and forth.
First we need to specify the connection to the server and we are setting it to point to out service.
On our server, we defined on hub and named it MessagesHub that had one method Send that was invoking a client method named sendMessageToClients. So currently the server is expecting all connected clients to handle the message in their sendMessagesToClient method. So this is how we can create a proxy and handle those messages.
EDITED: Very important, you must declare these handlers for the messages received from the server before you call connection.start(), otherwise you get inconsistent behavior and these will sometimes work and sometimes not!!!
So in our example when the server will receive a message from some of the clients, it will broadcast a message to all of the connected clients and they will update the appearance of the page with the latest received message.
Also we need some code to invoke the Send method on the hub and this is how we can do that, in this example we are attaching the logic on the send button click event.
In this functions we are making some basic validations if the message or alias is empty and then we are using the hub proxy object that we created previously to invoke the Send method on the hub.
So now we have build the server and the client and all the logic that we need to communicate the server and broadcast the messages. But if you try to run this you’ll see that the service will not be available for the client, so there is one more thing we need to do here in order to run and test this system.
Enabling CORS between the server and the client
If we were going to run the server and the client under the same domain we would not have this problem. But since our server and client are not under the same domain we would need to set the SignalR server to accept connections from clients that are from another domain. On the server project we would need to install the OWIN CORS library, again we can do that via the NuGet package console.
PM> Install-Package Microsoft.Owin.Cors
Now we need to update our startup class to allow us cross domain action, in this case we will allow all domains to access the server but we can put limitations there if needed. Also I’ve enabled detailed errors in the SignalR configuration which will allow us better debugging if problems appear.
So let’s start the server and open couple of clients to see if everything is working properly.
So now have a complete chat room that is driven with SignalR, implementation is basic and very fast to do, but it’s enough to demonstrate the possibilities on what can you do with this technology. In the next article I’m going to make a self hosted server with OWIN/Katana middle wear and try to use the same client.
The source code of this post is available on GitHub.
Enjoy your chatting,