教程:ASP.NET Core SignalR 入门Tutorial: Get started with ASP.NET Core SignalR

本教程介绍使用 SignalR 生成实时应用的基础知识。This tutorial teaches the basics of building a real-time app using SignalR. 您将学习如何:You learn how to:

  • 创建 Web 项目。Create a web project.
  • 添加 SignalR 客户端库。Add the SignalR client library.
  • 创建 SignalR 中心。Create a SignalR hub.
  • 配置项目以使用 SignalR。Configure the project to use SignalR.
  • 添加可将消息从任何客户端发送到所有连接客户端的代码。Add code that sends messages from any client to all connected clients.

最终将创建一个正常运行的聊天应用:At the end, you'll have a working chat app:

SignalR 示例应用

先决条件Prerequisites

创建 Web 应用项目Create a web app project

  • 从菜单中选择“文件”>“新建项目”。From the menu, select File > New Project.
  • 在“创建新项目”对话框中,选择“ASP.NET Core Web 应用程序”,然后选择“下一步” 。In the Create a new project dialog, select ASP.NET Core Web Application, and then select Next.
  • 在“配置新项目”对话框中,将项目命名为“SignalRChat”,然后选择“创建”。In the Configure your new project dialog, name the project SignalRChat, and then select Create.
  • 在“创建新的 ASP.NET Core Web 应用程序”对话框中,选择 .NET Core 和 ASP.NET Core 3.1 。In the Create a new ASP.NET Core web Application dialog, select .NET Core and ASP.NET Core 3.1.
  • 选择“Web 应用程序”以创建使用 Razor Pages 的项目,然后选择“创建” 。Select Web Application to create a project that uses Razor Pages, and then select Create.

Visual Studio 中的“新建项目”对话框

添加 SignalR 客户端库Add the SignalR client library

ASP.NET Core 3.1 共享框架中包含 SignalR 服务器库。The SignalR server library is included in the ASP.NET Core 3.1 shared framework. JavaScript 客户端库不会自动包含在项目中。The JavaScript client library isn't automatically included in the project. 对于此教程,使用库管理器 (LibMan) 从 unpkg 获取客户端库。For this tutorial, you use Library Manager (LibMan) to get the client library from unpkg. unpkg 是一个内容分发网络 (CDN),可分发在 npm(即 Node.js 包管理器)中找到的任何内容。unpkg is a content delivery network (CDN) that can deliver anything found in npm, the Node.js package manager.

  • 在“解决方案资源管理器”中,右键单击项目,然后选择“添加”>“客户端库” 。In Solution Explorer, right-click the project, and select Add > Client-Side Library.
  • 在“添加客户端库”对话框中,对于“提供程序”,选择“unpkg”。In the Add Client-Side Library dialog, for Provider select unpkg.
  • 对于“库”,输入 @microsoft/signalr@latestFor Library, enter @microsoft/signalr@latest.
  • 选择“选择特定文件”,展开“dist/browser”文件夹,然后选择“signalr.js”和“signalr.min.js”。Select Choose specific files, expand the dist/browser folder, and select signalr.js and signalr.min.js.
  • 将“目标位置”设置为 wwwroot/js/signalr/,然后选择“安装”。Set Target Location to wwwroot/js/signalr/, and select Install.

“添加客户端库”对话框 - 选择库

LibMan 创建 wwwroot/js/signalr 文件夹并将所选文件复制到该文件夹。LibMan creates a wwwroot/js/signalr folder and copies the selected files to it.

创建 SignalR 中心Create a SignalR hub

中心 是一个类,用作处理客户端 - 服务器通信的高级管道。A hub is a class that serves as a high-level pipeline that handles client-server communication.

  • 在 SignalRChat 项目文件夹中,创建 Hubs 文件夹。In the SignalRChat project folder, create a Hubs folder.
  • 在 Hubs 文件夹中,使用以下代码创建 ChatHub.cs 文件 :In the Hubs folder, create a ChatHub.cs file with the following code:
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);
        }
    }
}

ChatHub 类继承自 SignalR Hub 类。The ChatHub class inherits from the SignalR Hub class. Hub 类管理连接、组和消息。The Hub class manages connections, groups, and messaging.

可通过已连接客户端调用 SendMessage,以向所有客户端发送消息。The SendMessage method can be called by a connected client to send a message to all clients. 本教程后面部分将显示调用该方法的 JavaScript 客户端代码。JavaScript client code that calls the method is shown later in the tutorial. SignalR 代码是异步模式,可提供最大的可伸缩性。SignalR code is asynchronous to provide maximum scalability.

配置 SignalRConfigure SignalR

必须将 SignalR 服务器配置为将 SignalR 请求传递给 SignalR。The SignalR server must be configured to pass SignalR requests to SignalR.

  • 将以下突出显示的代码添加到 Startup.cs 文件。Add the following highlighted code to the Startup.cs file.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.HttpsPolicy;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using SignalRChat.Hubs;
    
    namespace SignalRChat
    {
        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)
            {
                services.AddRazorPages();
                services.AddSignalR();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Error");
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
    
                app.UseHttpsRedirection();
                app.UseStaticFiles();
    
                app.UseRouting();
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapRazorPages();
                    endpoints.MapHub<ChatHub>("/chatHub");
                });
            }
        }
    }
    

    这些更改将 SignalR 添加到 ASP.NET Core 依赖关系注入和路由系统。These changes add SignalR to the ASP.NET Core dependency injection and routing systems.

添加 SignalR 客户端代码Add SignalR client code

  • 使用以下代码替换 Pages\Index.cshtml 中的内容:Replace the content in Pages\Index.cshtml with the following code:

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

    前面的代码:The preceding code:

    • 创建名称以及消息文本的文本框和“提交”按钮。Creates text boxes for name and message text, and a submit button.
    • 使用 id="messagesList" 创建一个列表,用于显示从 SignalR 中心接收的消息。Creates a list with id="messagesList" for displaying messages that are received from the SignalR hub.
    • 包含对 SignalR 的脚本引用以及在下一步中创建的“chat.js”应用程序代码。Includes script references to SignalR and the chat.js application code that you create in the next step.
  • 在 wwwroot/js 文件夹中,使用以下代码创建 chat.js 文件 :In the wwwroot/js folder, create a chat.js file with the following code:

    "use strict";
    
    var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
    
    //Disable send button until connection is established
    document.getElementById("sendButton").disabled = true;
    
    connection.on("ReceiveMessage", function (user, message) {
        var msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
        var encodedMsg = user + " says " + msg;
        var li = document.createElement("li");
        li.textContent = encodedMsg;
        document.getElementById("messagesList").appendChild(li);
    });
    
    connection.start().then(function () {
        document.getElementById("sendButton").disabled = false;
    }).catch(function (err) {
        return console.error(err.toString());
    });
    
    document.getElementById("sendButton").addEventListener("click", function (event) {
        var user = document.getElementById("userInput").value;
        var message = document.getElementById("messageInput").value;
        connection.invoke("SendMessage", user, message).catch(function (err) {
            return console.error(err.toString());
        });
        event.preventDefault();
    });
    

    前面的代码:The preceding code:

    • 创建并启动连接。Creates and starts a connection.
    • 向“提交”按钮添加一个用于向中心发送消息的处理程序。Adds to the submit button a handler that sends messages to the hub.
    • 向连接对象添加一个用于从中心接收消息并将其添加到列表的处理程序。Adds to the connection object a handler that receives messages from the hub and adds them to the list.

运行应用Run the app

  • 按 Ctrl+F5 可运行应用而不进行调试。Press CTRL+F5 to run the app without debugging.
  • 从地址栏复制 URL,打开另一个浏览器实例或选项卡,并在地址栏中粘贴该 URL。Copy the URL from the address bar, open another browser instance or tab, and paste the URL in the address bar.
  • 选择任一浏览器,输入名称和消息,然后选择“发送消息”按钮。Choose either browser, enter a name and message, and select the Send Message button. 两个页面上立即显示名称和消息。The name and message are displayed on both pages instantly.

SignalR 示例应用

提示

  • 如果应用不起作用,请打开浏览器开发人员工具 (F12) 并转到控制台。If the app doesn't work, open your browser developer tools (F12) and go to the console. 可能会看到与 HTML 和 JavaScript 代码相关的错误。You might see errors related to your HTML and JavaScript code. 例如,假设将 signalr.js 放在不同于系统指示的文件夹中。For example, suppose you put signalr.js in a different folder than directed. 在这种情况下,对该文件的引用将不起作用,并且你将在控制台中看到 404 错误。In that case the reference to that file won't work and you'll see a 404 error in the console. 未找到 signalr.js 错误signalr.js not found error

  • 如果 Chrome 中出现 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY 错误,请运行这些命令以更新开发证书:If you get the error ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY in Chrome, run these commands to update your development certificate:

    dotnet dev-certs https --clean
    dotnet dev-certs https --trust
    

本教程介绍使用 SignalR 生成实时应用的基础知识。This tutorial teaches the basics of building a real-time app using SignalR. 您将学习如何:You learn how to:

  • 创建 Web 项目。Create a web project.
  • 添加 SignalR 客户端库。Add the SignalR client library.
  • 创建 SignalR 中心。Create a SignalR hub.
  • 配置项目以使用 SignalR。Configure the project to use SignalR.
  • 添加可将消息从任何客户端发送到所有连接客户端的代码。Add code that sends messages from any client to all connected clients.
    最后,你将拥有一个工作聊天应用:SignalR 示例应用At the end, you'll have a working chat app: SignalR sample app

先决条件Prerequisites

警告

如果使用 Visual Studio 2017,请参阅 dotnet/sdk 问题 #3124,以了解无法与 Visual Studio 一起使用的 .NET Core SDK 版本的信息。If you use Visual Studio 2017, see dotnet/sdk issue #3124 for information about .NET Core SDK versions that don't work with Visual Studio.

创建 Web 项目Create a web project

  • 从菜单中选择“文件”>“新建项目”。From the menu, select File > New Project.

  • 在“新建项目”对话框中,选择“已安装”>“Visual C#”>“Web”>“ASP.NET Core Web 应用” 。In the New Project dialog, select Installed > Visual C# > Web > ASP.NET Core Web Application. 将项目命名为“SignalRChat”。Name the project SignalRChat.

    Visual Studio 中的“新建项目”对话框

  • 选择“Web 应用”,以创建使用 Razor Pages 的项目。Select Web Application to create a project that uses Razor Pages.

  • 选择“.NET Core”目标框架,选择“ASP.NET Core 2.2”,然后单击“确定” 。Select a target framework of .NET Core, select ASP.NET Core 2.2, and click OK.

    Visual Studio 中的“新建项目”对话框

添加 SignalR 客户端库Add the SignalR client library

Microsoft.AspNetCore.App 元包中包括 SignalR 服务器库。The SignalR server library is included in the Microsoft.AspNetCore.App metapackage. JavaScript 客户端库不会自动包含在项目中。The JavaScript client library isn't automatically included in the project. 对于此教程,使用库管理器 (LibMan) 从 unpkg 获取客户端库。For this tutorial, you use Library Manager (LibMan) to get the client library from unpkg. unpkg 是一个内容分发网络 (CDN),可分发在 npm(即 Node.js 包管理器)中找到的任何内容。unpkg is a content delivery network (CDN) that can deliver anything found in npm, the Node.js package manager.

  • 在“解决方案资源管理器”中,右键单击项目,然后选择“添加”>“客户端库” 。In Solution Explorer, right-click the project, and select Add > Client-Side Library.

  • 在“添加客户端库”对话框中,对于“提供程序”,选择“unpkg”。In the Add Client-Side Library dialog, for Provider select unpkg.

  • 对于“库”,输入 @microsoft/signalr@3,然后选择不是预览版的最新版本。For Library, enter @microsoft/signalr@3, and select the latest version that isn't preview.

    “添加客户端库”对话框 - 选择库

  • 选择“选择特定文件”,展开“dist/browser”文件夹,然后选择“signalr.js”和“signalr.min.js”。Select Choose specific files, expand the dist/browser folder, and select signalr.js and signalr.min.js.

  • 将“目标位置”设置为 wwwroot/lib/signalr/,然后选择“安装”。Set Target Location to wwwroot/lib/signalr/, and select Install.

    “添加客户端库”对话框 - 选择文件和目标

    LibMan 创建 wwwroot/lib/signalr 文件夹并将所选文件复制到该文件夹。LibMan creates a wwwroot/lib/signalr folder and copies the selected files to it.

创建 SignalR 中心Create a SignalR hub

中心 是一个类,用作处理客户端 - 服务器通信的高级管道。A hub is a class that serves as a high-level pipeline that handles client-server communication.

  • 在 SignalRChat 项目文件夹中,创建 Hubs 文件夹。In the SignalRChat project folder, create a Hubs folder.

  • 在 Hubs 文件夹中,使用以下代码创建 ChatHub.cs 文件 :In the Hubs folder, create a ChatHub.cs file with the following code:

    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);
            }
        }
    }
    

    ChatHub 类继承自 SignalR Hub 类。The ChatHub class inherits from the SignalR Hub class. Hub 类管理连接、组和消息。The Hub class manages connections, groups, and messaging.

    可通过已连接客户端调用 SendMessage,以向所有客户端发送消息。The SendMessage method can be called by a connected client to send a message to all clients. 本教程后面部分将显示调用该方法的 JavaScript 客户端代码。JavaScript client code that calls the method is shown later in the tutorial. SignalR 代码是异步模式,可提供最大的可伸缩性。SignalR code is asynchronous to provide maximum scalability.

配置 SignalRConfigure SignalR

必须将 SignalR 服务器配置为将 SignalR 请求传递给 SignalR。The SignalR server must be configured to pass SignalR requests to SignalR.

  • 将以下突出显示的代码添加到 Startup.cs 文件。Add the following highlighted code to the Startup.cs file.

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    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; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.Configure<CookiePolicyOptions>(options =>
                {
                    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
    
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    
                services.AddSignalR();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Error");
                    app.UseHsts();
                }
    
                app.UseHttpsRedirection();
                app.UseStaticFiles();
                app.UseCookiePolicy();
                app.UseSignalR(routes =>
                {
                    routes.MapHub<ChatHub>("/chathub");
                });
                app.UseMvc();
            }
        }
    }
    

    这些更改将 SignalR 添加到 ASP.NET Core 依赖关系注入系统和中间件管道。These changes add SignalR to the ASP.NET Core dependency injection system and the middleware pipeline.

添加 SignalR 客户端代码Add SignalR client code

  • 使用以下代码替换 Pages\Index.cshtml 中的内容:Replace the content in Pages\Index.cshtml with the following code:

    @page
    <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>
        </div>
        <div class="row">
            <div class="col-12">
                <hr />
            </div>
        </div>
        <div class="row">
            <div class="col-6">&nbsp;</div>
            <div class="col-6">
                <ul id="messagesList"></ul>
            </div>
        </div>
    </div>
    <script src="~/lib/signalr/dist/browser/signalr.js"></script>
    <script src="~/js/chat.js"></script>
    

    前面的代码:The preceding code:

    • 创建名称以及消息文本的文本框和“提交”按钮。Creates text boxes for name and message text, and a submit button.
    • 使用 id="messagesList" 创建一个列表,用于显示从 SignalR 中心接收的消息。Creates a list with id="messagesList" for displaying messages that are received from the SignalR hub.
    • 包含对 SignalR 的脚本引用以及在下一步中创建的“chat.js”应用程序代码。Includes script references to SignalR and the chat.js application code that you create in the next step.
  • 在 wwwroot/js 文件夹中,使用以下代码创建 chat.js 文件 :In the wwwroot/js folder, create a chat.js file with the following code:

    "use strict";
    
    var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
    
    //Disable send button until connection is established
    document.getElementById("sendButton").disabled = true;
    
    connection.on("ReceiveMessage", function (user, message) {
        var msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
        var encodedMsg = user + " says " + msg;
        var li = document.createElement("li");
        li.textContent = encodedMsg;
        document.getElementById("messagesList").appendChild(li);
    });
    
    connection.start().then(function(){
        document.getElementById("sendButton").disabled = false;
    }).catch(function (err) {
        return console.error(err.toString());
    });
    
    document.getElementById("sendButton").addEventListener("click", function (event) {
        var user = document.getElementById("userInput").value;
        var message = document.getElementById("messageInput").value;
        connection.invoke("SendMessage", user, message).catch(function (err) {
            return console.error(err.toString());
        });
        event.preventDefault();
    });
    

    前面的代码:The preceding code:

    • 创建并启动连接。Creates and starts a connection.
    • 向“提交”按钮添加一个用于向中心发送消息的处理程序。Adds to the submit button a handler that sends messages to the hub.
    • 向连接对象添加一个用于从中心接收消息并将其添加到列表的处理程序。Adds to the connection object a handler that receives messages from the hub and adds them to the list.

运行应用Run the app

  • 按 Ctrl+F5 可运行应用而不进行调试。Press CTRL+F5 to run the app without debugging.
  • 从地址栏复制 URL,打开另一个浏览器实例或选项卡,并在地址栏中粘贴该 URL。Copy the URL from the address bar, open another browser instance or tab, and paste the URL in the address bar.

  • 选择任一浏览器,输入名称和消息,然后选择“发送消息”按钮。Choose either browser, enter a name and message, and select the Send Message button.

    两个页面上立即显示名称和消息。The name and message are displayed on both pages instantly.

    SignalR 示例应用

提示

如果应用不起作用,请打开浏览器开发人员工具 (F12) 并转到控制台。If the app doesn't work, open your browser developer tools (F12) and go to the console. 可能会看到与 HTML 和 JavaScript 代码相关的错误。You might see errors related to your HTML and JavaScript code. 例如,假设将 signalr.js 放在不同于系统指示的文件夹中。For example, suppose you put signalr.js in a different folder than directed. 在这种情况下,对该文件的引用将不起作用,并且你将在控制台中看到 404 错误。In that case the reference to that file won't work and you'll see a 404 error in the console.
未找到 signalr.js 错误signalr.js not found error

其他资源Additional resources