Few days ago, “Microsoft” released the version 2.1 of “.NET Core” and along with it the first version of “SignalR Core“. We are going to see how to create an ASP.NET Core 2.1 web application and use “TypeScript” and “WebPack” to bundle the front end.
To be sure to understand what’s below, ensure that you understand everything I explained in these posts:
The application that we are going to develop is a very simple chat application where people can just post messages to everyone. We won’t put much effort in the functionality in itself as the goal of this post is to learn how to setup a brand new project that works with all the aforementioned technologies.
Also, note that we won’t explain every configuration lines as most of them have been already explained in the two posts listed above, we will only focus on the new things.
Create the ASP.NET Core web application
We’ll start by creating the application using “Visual Studio”. To do so, ensure that the version 2.1 of .NET Core is installed along with at least the version 15.7 of “Visual Studio“. Then, create a new project of type “ASP.NET Core Web Application”:
As we love doing everything from scratch in order to really understand what we do, let’s select the “Empty” template in the following screen and make sure that “ASP.NET Core 2.1” is selected in the version dropdown.
Configure WebPack and TypeScript
Now, we are going to configure “WebPack” and “TypeScript” in order to have the front end part of the application. Even though there will be a “CSS” file, we won’t put much effort in the design of the application as this is not the important thing here.
Start by installing all the package that we are going to need:
yarn add clean-webpack-plugin css-loader html-webpack-plugin mini-c
ss-extract-plugin ts-loader typescript webpack webpack-cli -D
Then add a new “npm” script to launch “webpack” in “watch” mode:
Note that we are not using “webpack-dev-server” as the web server will be provided by the “dotnet cli” tool, so we are just using the “watch” mode in order to re-bundle our application at every changes.
Now, add a file called “webpack.config.js” in the root of your project with the following content:
Here are the things to pay attention to:
- The “output” part has been defined to override its default value. Indeed, if you don’t instruct it otherwise, “webpack” will output the bundle in the “dist” folder, however, we want it to do so in the “wwwroot” instead in order to be able to run our application with the “dotnet cli”.
The next file to create is “./src/index.html” which is our “HTML” template used to generate the homepage of our web application:
This “HTML” simply displays a zone where messages will be displayed and an input zone where the user will be able to send messages from. In order to style this page a bit (just a tiny bit), add a file called “./src/assets/css/main.css” with the following content:
Before we create our main “TypeScript” file, we need to add a “./tsconfig.json” file at the root of our project in order to configure the “TypeScript” compilation:
Once again, we only define the minimal configuration to ensure that our code will be generated as “es5” compatible one. Now, we can create our “./src/index.ts” file:
We won’t let the possibility to the user to choose his nickname so we generate one based on the current date at line 6. Then, we add an event receiver to the input to call the “send” function if the user presses the “Enter” key. We do the same for the event “click” of the “Send” button. The “send” function is where the magic is going to happen but first, we need to configure our .NET Core application to be able to receive web socket messages.
Configure the ASP.NET Core application
Right now, if you run the following command in a terminal and browse your web application, the only thing you’ll get is a blank page with “Hello World!” displayed.
dotnet watch run
This command is the “dotnet cli” equivalent to the “watch” command of “WebPack”. Basically, it will run a web server to host your application and re-compile the source as soon as a file changes.
The first thing to ensure is that our “index.html” page is correctly loaded instead of the default “Hello World!” message. To do so, replace the block:
The first line ensures that the server will fallback on default documents (such as “index.html” or “index.aspx”) if the user enters the URL of your web application without a page name while the second line ensures that the server tries to load static files such our “index.html” page.
The next step is to install “SignalR” with the following command:
Then let’s configure our application by adding the “SignalR” service to it. To do so, add the following line in the “ConfigureServices” method:
Now we are going to define an “URL” that “SignalR” will listen to in order to allow communication between the client and the server via “web sockets”. So add the following block at the end of the “Configure” method:
A “hub” is a C# class that is responsible for handling the communication between the client and the server. We created a route “/hub” and indicated that the “ChatHub” class will have to be used to handle this communication. As this class does not exist yet in our project, add the file “./Core/ChatHub.cs”:
Don’t forget to add a “using” statement to import the “Core” namespace in our “Startup.cs” file.
Right now, we have an application that displays an ugly form to send messages but nothing happens when we actually try to do so. On the other hand, the server is just listening to a specific route but don’t do anything with sent messages. We’re going to change that by modifying our “./src/index.ts” file to allow the user to send messages. To do so, start by installing the “node” package of “signalR” by running the command:
yarn add @aspnet/signalr -S
Then, add the following “import” at the beginning of the file:
We are now ready to establish the connection with the server. So add the following lines below the declaration of the “username” constant:
First of all, we create a new connection to our “web socket” server using the URL “/hub”. Then, we can start this connection via the function “start” and if this one fails, we just display the error on the page.
The idea behind “SignalR” is pretty simple, you exchange messages between a client and a server and each message has a specific name. For example, you can have messages with the name “messageReceived” that execute the logic responsible for displaying the new message in the messages zone. Listening to a specific message can be done via the “on” function and you can listen to any number of message names that you want. It is also possible to pass parameters to the message, like the author’s name and the content of the message received and that’s exactly what we do here. Once a new message is received (with the name “messageReceived”), we create a new div with the author’s name and the message content in its “innerHTML” property and we add it to the main “div” displaying the messages. Then, just to show off, we scroll down to the bottom of the main “div” in order to display the last received message if there are too many of them.
Now that we are able to receive messages, we need to be able to send them, so add the following code in the “send “function:
Sending a message through the “web socket” connection is as easy as using the “send” method with the message name as first parameter and the message parameters as the rest of the parameters, so here, we just send a “newMessage” message with the username and the content of the “input” to the server and if it works, we remove the content of the “input”.
The last thing we need to do is broadcast this message to all the connected users when the server receives it. So add the following method to your “ChatHub” class:
As you can see, it is even simpler to receive message in “C#” than in “TypeScript”. Indeed, we don’t need a “on” function to receive all the messages then call the correct function depending on the message name, all we need is a function named like the message name. For example, the “TypeScript” code sends a “newMessage” message, so in the “C#” code, we just need a “NewMessage” method that expects the parameters sent by the client and we’re good to go.
Here, we just call the method “SendAsync” on “Clients.All” (which is a list of all currently connected users) to broadcast the received message to everyone.
And… That’s it! You can now browse your site and open multiple instance of “Chrome” to see that when you send a message, all the connected clients also receive it, it’s as simple as that.
As I said in the introduction, this post does not aim at going deep into “SignalR”, indeed, I just wanted to show the different steps to have a minimal configuration for a ASP.NET Core Web Application using SignalR, TypeScript with a front end part bundled with “WebPack”.