The first official release of SignalR for ASP.NET Core – alpha1 – was just released. In this release, all SignalR components were rewritten to make SignalR simpler, easier to use and more reliable.
Setting up the Server
Let’s start from creating an empty ASP.NET Core application. We can do that from command line by running the
dotnet new web command. (See this step on github).
Once the application is created we can start the server with
dotnet run and make sure it works by navigating to
http://localhost:5000 from a browser.
After we ensured that the application runs we can add SignalR server components. First, we need to add a reference to the SignalR package to the SignalRChat.csproj file (See this step on github).
Now we can add the Chat Hub class – we will just copy the code from tutorial and tweak a few things. This is how the hub class looks after the changes:
public class ChatHub : Hub
public void Send(string name, string message)
// Call the broadcastMessage method to update clients.
Clients.All.InvokeAsync("broadcastMessage", name, message);
The changes we made were only cosmetic – we removed the reference to the
System.Web namespace, added
'Core' to the
Microsoft.AspNet.SignalR so that it reads
Microsoft.AspNetCore.SignalR. We also changed how we invoke the client-side method by passing the method name as the first parameter to the
InvokeAsync call. (See this step on github).
Now that we created a hub we need to configure the application to be aware of SignalR and to forward SignalR related messages to our hub. It’s as easy as calling
AddSignalR extension method in the
ConfigureServices method of our
Startup class and mapping the hub with the
UseSignalR method. We will also add the static files middleware which will be responsible for serving static files. The Startup class should look like this:
public class Startup
public void ConfigureServices(IServiceCollection services)
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
(See this step on github).
And this is all the work we had to do create a functional SignalR chat server. Now we can focus on the client side.
tag, as well as, typings and modules that can be consumed from TypeScript. To get the client to your machine you need to install npm if you haven’t already and run:
npm install @aspnet/signalr-client
The client will be installed in the
node_modules folder and you can find the necessary files to include in the
node_modules/@aspnet/signalr-client/dist/browser folder. You may wonder why there are so many files in this folder and what purpose they serve. Let’s go over them then and explain.
First, you will find that there are two sets of files – files that contain
Another interesting set of files are files containing
You will also find that each file has a
min counterpart. These are just minified versions of the corresponding files. You will want to use the minified versions in production but debugging is much easier with non-minified files so you may want to use non-minified versions during development.
Finally, there is also the
third-party-notices.txt file. These are notices for the msgpack5 library and its dependencies used in the MessagePack hub protocol implementation.
First, let’s copy all the files from the
node_modules/@aspnet/signalr-client/dist/browser folder to a new
scritps/signalr folder under the
wwwroot. (See this step on github).
After the files are copied, let’s create the
index.html file in the wwwroot folder and paste the contents of the html file from the tutorial. (See this step on github).
If you try to run the application at this point it will not work. The
index.html has references to files like the jQuery library or the old SignalR client which don’t exist. Let’s fix that. Note that even though jQuery is no longer required to the new SignalR client I will continue to use it to minimize the number of changes I need to make. All in all this is not a tutorial on how to remove jQuery from your app so let’s not get sidetracked. Let’s start from sorting out the scripts situation. For jQuery, I will replace the link with the one to the jQuery CDN. For SignalR, I will replace the link to the
signalR-2.2.1.min.js file with
signalR-client-1.0.0-alpha1.js (feel free to use the ES5 version if you are using a browser that don’t support ES6 features) and remove the link to hubs since hub proxies are currently not supported. (See this step on github (github trick – notice that the link ends with
?w=1 – try removing it and see what happens. Very useful when reviewing some PRs)).
Now we can finally fix the code. Fortunately, this is not a lot of changes:
- Instead of using proxies we will just create a new
- To register the callback for the client side
broadcastMessage method we will use the
- We will replace the
done method used by jQuery deferreds to the
then used by ES6 promises
- We will invoke hub methods with the
(See this step on github).
That’s pretty much it. If you run the application now you should be able to send and receive messages.
First, make sure that you have a recent TypeScript compiler installed – run
tsc --version from command line. If running the command fails or you have an older version installed install the latest one using this command:
npm install typescript -g
After installing or updating the typescript compiler we will initialize a new project by running
in the project folder. This will create a
tsconfig.json file which will look like this:
after performing some cleanup. We will also add a new chat.ts file which we will leave empty for now. If you run the
tsc command from project root you should see an almost empty
chat.js file generated from your
chat.ts file. (See this step on github).
To be able to add and restore dependencies the client will need, let’s create a
package.json file by executint the
npm init command. We will leave default values for almost all settings except for the project name which needs to be lowercase.
PS C:\source\SignalRChat\SignalRChat> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (SignalRChat) signalrchat
entry point: (chat.js)
About to write to C:\source\SignalRChat\SignalRChat\package.json:
"test": "echo \"Error: no test specified\" && exit 1"
Is this ok? (yes)
Now let’s add our dependencies – signalr-client, jquery and jquery typings (they enable using jquery from TypeScript). We will use the
--save-dev option to save the dependencies as dev dependencies in the
npm install @aspnet/signalr-client --save-dev
npm install jquery --save-dev
npm install @types/jquery --save-dev
We also need to install
browserify – a tool which we will use to create the final script to be used by the browser:
npm install -g browserify
(See this step on github).
We can now start working on the code. First, we need to import the dependencies we are going to use. We can do that by adding the following two lines at the top of our chat.ts file:
import * as signalR from "@aspnet/signalr-client"
import * as $ from "jquery
Now we can move the script from our
.html file to the
.ts file. If you do that and play a little bit with the code you will notice that intellisense now tells you about class members and function parameters and if you press F12 (in Visual Studio Code) it will take you to the function header. Another thing, you will see is an error on line 5. This TypeScript telling you that there is a type mismatch for the parameter passed to the jQuery
val() function – the
prompt() function can return
null which is not a valid input for the
In our case we know that prompt will return
string so we will just cast the result to
string to suppress the error.
Since we moved the function to the
index.html file. We can also remove all the
tags since we no longer depend on them to bring dependencies (we also already deleted the scripts). (See this step on github).
Let’s compile our
chat.ts file now by running
tsc command. If you look at the generated
chat.js file you will notice that it looks pretty much the same as the source
chat.ts file with some additional lines at the top. You will also notice that it does not have the required dependencies (i.e. signalr-client and jquery). This is where
browserify comes into play. We will use
browserify to generate the final version of the file with all the dependencies. Let’s run the following command (you may need to create the
wwwroot/scripts folder if one does not exist) from the project folder:
browserify .\chat.js -o .\wwwroot\scripts\chat.js
Take a look at the
chat.js file that was created by
browserify and now you will see that the file is much bigger and contains all the required dependencies. If we include this file in our
index.html with the
tag, start the application and open in the browser you will see that it works and you can send and receive messages. (See this step on github). We could even automate build steps (e.g. with
gulp) but it’s out of scope for this post.