GitHub profile
.NET Framework .NET C# VB.NET LINQ ASP.NET Web API REST SignalR Windows Forms WPF WCF RabbitMQ PHP SQL Server MySQL PostgreSQL MariaDB SQLite MongoDB ADO.NET ORM Entity Framework Dapper XML JSON HTML5 CSS3 Bootstrap JavaScript jQuery Angular React TypeScript NPM Blazor UI/UX Responsive Web Design Redis Elasticsearch GraphQL Grafana Agile Scrum Kanban Windows Server IIS PowerShell Active Directory TFS Azure Automation Software Reverse Engineering Performance Optimization Git Jira/Confluence CI/CD TeamCity SOLID KISS DRY YAGNI
Always will be ready notify the world about expectations as easy as possible: job change page

Integrating SignalR with React TypeScript and ASP.NET Core

Created: Jun 26, 2021
Views: 382

SignalR is a popular software library that allows you send server code to client-side applications, like a React application. This tutorial will show you how to install SignalR on both your ASP.NET Core and React Typescript application.

Creating your Applications

When creating your ASP.NET Core application, there is an option to create your application with an React.js application.

Once you have successfully created your ASP.NET Core application, we are going to delete everything inside the "ClientApp" folder, including the folder itself. The "ClientApp" folder contains the React app created when we set up our ASP.NET Core application. We want to recreate this!

At this stage, you want to make sure that you have NodeJS installed on your machine. When NodeJS is installed, you can install packages from the NPM package library using "npm" at the start of your command line prompt. You may also want to install Yarn.

Yarn is similar to NPM, but they state that it "caches every package it has downloaded, so it never needs to download the same package again.".

For the purposes of this tutorial, we are going to use Yarn in our command line prompts.

You can install Yarn by running the following in your favourite command prompt application:

npm install yarn -g

Notice the "-g" parameter at the end. This ensures that it is installed globally on your machine.

Now going back to recreating your React app. It's time to recreate it with TypeScript. In your command prompt, change directory to the root folder of your ASP.NET Core application. Run the following command prompt:

yarn create react-app clientapp --template typescript

Note in the above command line that "clientapp" is all lowercase. It will not allow you to use uppercase letters. As a result of this command line prompt, your React application will be created into "clientapp". More importantly, it will create it using TypeScript.

Installing SignalR on your React App

Using the command line prompt again, change the directory so you are inside the "clientapp" folder. We are going to install the @microsoft/signalr application from NPM. You can do that by running the following command prompt:

yarn install @microsoft/signalr

As a result, this will install the SignalR library into our React app. Now that we have SignalR in our React app, we are going to make some code changes inside App.tsx which are shown below:

// App.tsx
import React, { useState, useEffect } from "react";
import "./App.css";
import * as signalR from "@microsoft/signalr";
const App: React.FC = () => {
  // Builds the SignalR connection, mapping it to /chat
  const hubConnection = new signalR.HubConnectionBuilder()
  // Starts the SignalR connection
  hubConnection.start().then(a => {
    // Once started, invokes the sendConnectionId in our ChatHub inside our ASP.NET Core application.
    if (hubConnection.connectionId) {
      hubConnection.invoke("sendConnectionId", hubConnection.connectionId);
    const SignalRTime: React.FC = () => {      
      // Sets the time from the server
      const [time, setTime] = useState<string | null>(null);
      useEffect(() => {
        hubConnection.on("setTime", message => {
      return <p>The time is {time}</p>;
    const SignalRClient: React.FC = () => {
      // Sets a client message, sent from the server
      const [clientMessage, setClientMessage] = useState<string | null>(null);
      useEffect(() => {
        hubConnection.on("setClientMessage", message => {
      return <p>{clientMessage}</p>
    return <><SignalRTime /><SignalRClient /></>;
export default App;

At present, this code will throw an error. The next step is to integrate SignalR into your ASP.NET Core application.

Installing SignalR on your ASP.NET Core application

Load up Visual Studio 2019 and open your ASP.NET Core application. Go to Tools -> NuGet Package Manager -> Package Manager Console. Run the following command inside the Package Manager Console:

Install-Package Microsoft.AspNetCore.SignalR.Client

This will install SignalR in your ASP.NET Core Application from the NuGet Package Library. Then open up your Startup.cs file and add the following line inside your ConfigureServices method:


Next, create your SignalR hub. This will inherit the Hub class from the SignalR package. Named ChatHub, we will include a SendConnectionId method. This method is invoked when we start our SignalR connection in our React app:

// ChatHub.cs
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
namespace SignalR_Test.Hubs
    public class ChatHub : Hub
        public async Task SendConnectionId(string connectionId)
            await Clients.All.SendAsync("setClientMessage", "A connection with ID '" + connectionId + "' has just connected");

Inside the SendConnectionId method, we are sending a message to all clients connected. We are sending this message through the setClientMessage method that gets listened out for in our React app.

Now, going back to our Startup.cs file, we are going to find our Configure method. We are going to add a new parameter called "hostApplicationLifetime". This parameter is of type IHostApplicationLifetime (or IApplicationLifetime in .NET Core 2). Then we will add the following code inside our Configure method: 

hostApplicationLifetime.ApplicationStarted.Register(() =>
                var serviceProvider = app.ApplicationServices;
                var chatHub = (IHubContext<ChatHub>)serviceProvider.GetService(typeof(IHubContext<ChatHub>));
                var timer = new System.Timers.Timer(1000);
                timer.Enabled = true;
                timer.Elapsed += delegate (object sender, System.Timers.ElapsedEventArgs e) {
                    chatHub.Clients.All.SendAsync("setTime", DateTime.Now.ToString("dddd d MMMM yyyy HH:mm:ss"));

What this does is when the application has started, it starts up a timer which refreshes every second. After every second, it will send the time to all clients connected through SignalR. It will use the setTime method and will send the current server time.

Here is the full code for Startup.cs: 

// Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SignalR_Test.Hubs;
using System;
namespace SignalR_Test
    public class Startup
        public Startup(IConfiguration configuration)
            Configuration = configuration;
        public IConfiguration Configuration { get; }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
            // In production, the React files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
                configuration.RootPath = "ClientApp/build";
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime hostApplicationLifetime)
            if (env.IsDevelopment())
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see
            app.UseEndpoints(endpoints =>
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
            app.UseSpa(spa =>
                spa.Options.SourcePath = "ClientApp";
                if (env.IsDevelopment())
                    spa.UseReactDevelopmentServer(npmScript: "start");
            hostApplicationLifetime.ApplicationStarted.Register(() =>
                var serviceProvider = app.ApplicationServices;
                var chatHub = (IHubContext<ChatHub>)serviceProvider.GetService(typeof(IHubContext<ChatHub>));
                var timer = new System.Timers.Timer(1000);
                timer.Enabled = true;
                timer.Elapsed += delegate (object sender, System.Timers.ElapsedEventArgs e) {
                    chatHub.Clients.All.SendAsync("setTime", DateTime.Now.ToString("dddd d MMMM yyyy HH:mm:ss"));

Once started, your application should look like this:

SignalR with React Typescript and ASP.NET Core


For the record, the versions I'm using in this tutorial are as follows:

  • ASP.NET Core 3.1.1
  • Microsoft.AspNetCore.SignalR.Client 3.1.1
  • react 16.12.0
  • react-scripts 3.3.0
  • typescript 3.7.2
  • @microsoft/signalr 3.1.0

A Bug with WebSocket when running a React App Securely

You may discover that sometimes SignalR works and sometimes it doesn't in a React app. You may see an error similar to this in your browser development tools:

WebSocket connection to 'ws://localhost:44357/sockjs-node' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET

Now, SignalR uses Websocket to forge a connection between the client and browser (assuming your browser has support for Websocket). And like the HTTP protocol, Websocket's protocol is different when using a secure connection. When secure, it will use the wss protocol. The ws protocol is used when it's not secure.

However, there is a bug with the "react-dev-utils" package that is a package installed from NPM. Inside webpackHotDevClient.js, it attempts to connect to the WebpackDevServer via a socket. However, the protocol it states in that connection is ws. Here is the snippet of code:

// Connect to WebpackDevServer via a socket.
var connection = new WebSocket(
    protocol: 'ws',
    hostname: window.location.hostname,
    port: window.location.port,
    // Hardcoded in WebpackDevServer
    pathname: '/sockjs-node',

As mentioned above, the "ws" protocol is the non-secure connection for WebSocket. This gives us a problem when running our application securely. There are three ways we can go about this:

  • Change the protocol to "wss" inside webpackHotDevClient.js
  • Specify SignalR to use LongPulling (an older method of integrating server and client applications)
  • Run the application non-securely

Now, I've mentioned in previous posts about the importance about security, so that rules out the last option. I'm one who likes using new technology so that rules out the second option. So the only other option is to change the protocol to wss.

But it's not as simple as that! Because "react-dev-utils" is a package downloaded from NPM, it means that any one else using your React application will have to make that change. You will need to make sure that you document this change in your installation instructions.

You can see a full demonstration of this bug in action by watching the video below:

Apr 24, 2022
Author: Dr Vin
Let’s find out which one is better .Net 6 or .Net 5 and how .Net has changed the game of software development.In the past, I have briefly talked about the Dot Net 6 framework that was released last year in...
Jun 15, 2021
Author: Emre Kizildas
Hi everyone, this article include encrypting your database columns with EntityFramework. Your database providers can be MSSQL or PostgreSQL.Considering that some database columns contain confidential data, it is of great importance that the data is encrypted in case of capture...
Jan 15, 2023
Author: Destiny Erhabor
Defined long ago, the SOLID principles are intended to improve the readability, adaptability, extensibility, and maintainability of object-oriented designs. The five SOLID principles of object-oriented class design facilitate the development of understandable, tested software that many developers can use at...
Jul 16, 2020
Author: Kannan Eswar
In this blog, I am going to provide a walkthrough on developing REST APIs using ASP.NET Core 3.1, connecting with existing databases using Entity Framework, creating a JWT token, and securing APIs. I am going to develop a sample application...
Send message
Your name

© 1999–2023 WebDynamics
1980–... Sergey Drozdov
Area of interests: .NET | .NET Core | C# | ASP.NET | Windows Forms | WPF | Windows Phone | HTML5 | CSS3 | jQuery | AJAX | MS SQL Server | Transact-SQL | ADO.NET | Entity Framework | IIS | OOP | OOA | OOD | WCF | WPF | MSMQ | MVC | MVP | MVVM | Design Patterns | Enterprise Architecture | Scrum | Kanban