Get started with SignalR on ASP.NET Core

By Rachel Appel

This tutorial teaches the basics of building a real-time app using SignalR for ASP.NET Core.


This tutorial demonstrates the following SignalR development tasks:

  • Create a SignalR on ASP.NET Core web app.
  • Create a SignalR hub to push content to clients.
  • Modify the Startup class and configure the app.

View or download sample code (how to download)

Install the following software:

Create an ASP.NET Core project that hosts SignalR client and server

  1. Use the File > New Project menu option and choose ASP.NET Core Web Application. Name the project SignalRChat.

    New Project dialog in Visual Studio

  2. Select Web Application to create a project using Razor Pages. Then select OK. Be sure that ASP.NET Core 2.1 is selected from the framework selector, though SignalR runs on older versions of .NET.

    New Project dialog in Visual Studio

Visual Studio includes the Microsoft.AspNetCore.SignalR package containing its server libraries as part of its ASP.NET Core Web Application template. However, the JavaScript client library for SignalR must be installed using npm.

  1. Run the following commands in the Package Manager Console window, from the project root:

    npm init -y
    npm install @aspnet/signalr
  2. Create a new folder named “signalr” inside the lib folder in your project. Copy the signalr.js file from node_modules@aspnetsignalrdistbrowser to this folder.

Create the SignalR Hub

A hub is a class that serves as a high-level pipeline that allows the client and server to call methods on each other.

  1. Add a class to the project by choosing File > New > File and selecting Visual C# Class. Name the file ChatHub.

  2. Inherit from Microsoft.AspNetCore.SignalR.Hub. The Hub class contains properties and events for managing connections and groups, as well as sending and receiving data.

  3. Create the SendMessage method that sends a message to all connected chat clients. Notice it returns a Task, because SignalR is asynchronous. Asynchronous code scales better.

    using Microsoft.AspNetCore.SignalR;
    using System.Threading.Tasks;
    namespace SignalRChat.Hubs
        public class ChatHub : Hub
            public async Task SendMessage(string user, string message)
                await Clients.All.SendAsync("ReceiveMessage", user,message);

Configure the project to use SignalR

The SignalR server must be configured so that it knows to pass requests to SignalR.

  1. To configure a SignalR project, modify the project’s Startup.ConfigureServices method.

    services.AddSignalR adds SignalR as part of the middleware pipeline.

  2. Configure routes to your hubs using UseSignalR.

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using SignalRChat.Hubs;
    namespace SignalRChat
        public class Startup
            public Startup(IConfiguration configuration)
                Configuration = configuration;
            public IConfiguration Configuration  get; 
            public void ConfigureServices(IServiceCollection services)
                services.Configure<CookiePolicyOptions>(options =>
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                services.AddCors(options => options.AddPolicy("CorsPolicy",
                builder =>
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
                if (env.IsDevelopment())
                app.UseSignalR(routes =>

Create the SignalR client code

  1. Add a JavaScript file, named chat.js, to the wwwrootjs folder. Add the following code to it:

    // The following sample code uses modern ECMAScript 6 features 
    // that aren't supported in Internet Explorer 11.
    // To convert the sample for environments that do not support ECMAScript 6, 
    // such as Internet Explorer 11, use a transpiler such as 
    // Babel at 
    // See Es5-chat.js for a Babel transpiled version of the following code:
    const connection = new signalR.HubConnectionBuilder()
    connection.on("ReceiveMessage", (user, message) => 
        const msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
        const encodedMsg = user + " says " + msg;
        const li = document.createElement("li");
        li.textContent = encodedMsg;
    connection.start().catch(err => console.error(err.toString()));
    document.getElementById("sendButton").addEventListener("click", event => 
        const user = document.getElementById("userInput").value;
        const message = document.getElementById("messageInput").value;
        connection.invoke("SendMessage", user, message).catch(err => console.error(err.toString()));
  2. Replace the content in PagesIndex.cshtml with the following code:

        <div class="container">
            <div class="row">&nbsp;</div>
            <div class="row">
                <div class="col-6">&nbsp;</div>
                <div class="col-6">
                    User..........<input type="text" id="userInput" />
                    <br />
                    Message...<input type="text" id="messageInput" />
                    <input type="button" id="sendButton" value="Send Message" />
            <div class="row">
                <div class="col-12">
                    <hr />
            <div class="row">
                <div class="col-6">&nbsp;</div>
                <div class="col-6">
                    <ul id="messagesList"></ul>
        <script src="~/lib/signalr/signalr.js"></script>    
        <script src="~/js/chat.js"></script>
        @*<script src="~/js/es5-chat.js"></script>*@

    The preceding HTML displays name and message fields, and a submit button. Notice the script references at the bottom: a reference to SignalR and chat.js.

Run the app

  1. Select Debug > Start without debugging to launch a browser and load the website locally. Copy the URL from the address bar.

  2. Open another browser instance (any browser) and paste the URL in the address bar.

  3. Choose either browser, enter a name and message, and click the Send button. The name and message are displayed on both pages instantly.


Introduction to ASP.NET Core SignalR