How to build chat Server and Client with SignalR and ASP.NET Web API (Part 2)

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).

ChatClients.png

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.
Another thing that I didn’t like was that in every article and showcase about SignalR the authors were using some frontend binding framework (KnockoutJS, AngularJS, Angular2 etc.) and I got the feeling that more than the half of the code and articles was dedicated for demonstrating the usage of these framework which will also make things to look more complex than they really are. In my example I’m just using plain JavaScript and jQuery which we must include anyways in our client project as a prerequisite for SignalR.

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

CreatingWebAPIApplication.png

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.

WebAPITemplate.png

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.

Install-Package Microsoft.AspNet.SignalR

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

app.MapSignalR();

SignalROwinMiddlewear.png

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

AddHub.png

This template will create sample hub for us

BasicHub.png

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.

SendMessageToAllClients.png

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.

In my example, I’m not using this auto-generated proxy because I didn’t want to include in the client project something that is build on the server project, but it’s perfectly ok if you want to use it. Here you can find step by step SignalR client build with and without using the generated proxy, so it will be a good reference for learning and using this proxy  -> ASP.NET SignalR Hubs API Guide – JavaScript Client.

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.

First we need to add SignalR JavaScript API libraries, for this I’m adding SignalR via Nuget. All you’ll need is the JS and you can delete the .dll or simply not publish those because this site will be pure html.

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:

ChatClientPage
Just note that we need to add some dependencies here

ScriptIncluidesIndex.png

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.

CreateHubConnection.png

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!!!

HubProxy.png

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.

SendMessageToHub.png

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.

EnableCORS.png

So let’s start the server and open couple of clients to see if everything is working properly.

ChatSample.png

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,

J.

Advertisements

3 thoughts on “How to build chat Server and Client with SignalR and ASP.NET Web API (Part 2)

  1. Well done .. Keep it up.

    I have started learning SignalR last two weeks. And unfortunately, all Microsoft documentations regarding SignalR is really confusing. They have SignalR, ASP.NET SignalR, ASP.NET Core SignalR, Azure SignalR, etc.., when I try to find packages they used during the tutorial, I found mostly are out-dated!!!

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s