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

本文内容

本教程介绍生成使用 SignalR 的实时应用的基础知识。您将学习如何:

  • 创建 Web 项目。
  • 添加 SignalR 客户端库。
  • 创建 SignalR 中心。
  • 配置项目以使用 SignalR。
  • 添加可将消息从任何客户端发送到所有连接客户端的代码。

最终将创建一个正常运行的聊天应用:

SignalR 示例应用

先决条件Prerequisites

Visual Studio Code 说明使用用于 ASP.NET Core 的 .NET Core CLI 开发功能,如项目创建。可在任何平台(macOS、Linux 或 Windows)上或在任何代码编辑器中遵循这些说明。如果使用 Visual Studio Code 以外的其他内容,则可能需要进行少量更改。

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

  • 从菜单中选择“文件”>“新建项目” 。

  • 在“创建新项目”对话框中,选择“ASP.NET Core Web 应用程序”,然后选择“下一步” 。

  • 在“配置新项目”对话框中,为项目 SignalRChat 命名,然后选择“创建” 。

  • 在“创建新的 ASP.NET Core Web 应用程序”对话框中,选择“.NET Core”和“ASP.NET Core 3.0” 。

  • 选择“Web 应用程序”以创建使用 Razor Pages 的项目,然后选择“创建” 。

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

  • 在将要在其中创建新项目文件夹的文件夹中打开集成终端

  • 运行以下命令:

  1. dotnet new webapp -o SignalRChat
  2. code -r SignalRChat
  • 从菜单中选择“文件”>“新建解决方案” 。

  • 选择“.NET Core”>“应用”>“Web 应用程序”(不要选择“Web 应用程序(Model-View-Controller)”),然后选择“下一步” 。

  • 确保“目标框架”设置为“.NET Core 3.0”,然后选择“下一步” 。

  • 将项目命名为“SignalRChat”,然后选择“创建” 。

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

SignalR 服务器库包含在 ASP.NET Core 3.0 共享框架中。JavaScript 客户端库不会自动包含在项目中。对于此教程,使用库管理器 (LibMan) 从 unpkg 获取客户端库。unpkg 是一个内容分发网络 (CDN),可以分发在 npm(即 Node.js 包管理器)中找到的任何内容。

  • 在“解决方案资源管理器”中,右键单击项目,然后选择“添加”>“客户端库” 。

  • 在“添加客户端库” 对话框中,对于“提供程序” ,选择“unpkg” 。

  • 对于“库” ,输入 @microsoft/signalr@latest

  • 选择“选择特定文件” ,展开“dist/browser” 文件夹,然后选择“signalr.js” 和“signalr.min.js” 。

  • 将“目标位置” 设置为 wwwroot/js/signalr/ ,然后选择“安装” 。

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

LibMan 创建 wwwroot/js/signalr 文件夹并将所选文件复制到该文件夹。

  • 在集成终端中,运行以下命令以安装 LibMan。
  1. dotnet tool install -g Microsoft.Web.LibraryManager.Cli
  • 使用 LibMan 运行以下命令,以获取 SignalR 客户端库。可能需要等待几秒钟的时间才能看到输出。
  1. libman install @microsoft/signalr@latest -p unpkg -d wwwroot/js/signalr --files dist/browser/signalr.js --files dist/browser/signalr.min.js

参数指定以下选项:

  • 使用 unpkg 提供程序。
  • 将文件复制到 wwwroot/js/signalr 目标。
  • 仅复制指定的文件。
    输出如下所示:
  1. wwwroot/js/signalr/dist/browser/signalr.js written to disk
  2. wwwroot/js/signalr/dist/browser/signalr.min.js written to disk
  3. Installed library "@microsoft/signalr@latest" to "wwwroot/js/signalr"
  • 在“终端” 中,运行以下命令以安装 LibMan。
  1. dotnet tool install -g Microsoft.Web.LibraryManager.Cli
  • 导航到项目文件夹(包含 SignalRChat.csproj 文件的文件夹)。

  • 使用 LibMan 运行以下命令,以获取 SignalR 客户端库。

  1. libman install @microsoft/signalr@latest -p unpkg -d wwwroot/js/signalr --files dist/browser/signalr.js --files dist/browser/signalr.min.js

参数指定以下选项:

  • 使用 unpkg 提供程序。
  • 将文件复制到 wwwroot/js/signalr 目标。
  • 仅复制指定的文件。
    输出如下所示:
  1. wwwroot/js/signalr/dist/browser/signalr.js written to disk
  2. wwwroot/js/signalr/dist/browser/signalr.min.js written to disk
  3. Installed library "@microsoft/signalr@latest" to "wwwroot/js/signalr"

创建 SignalR 中心Create a SignalR hub

中心是一个类,用作处理客户端 - 服务器通信的高级管道。

  • 在 SignalRChat 项目文件夹中,创建 Hubs 文件夹 。

  • 在 Hubs 文件夹中,使用以下代码创建 ChatHub.cs 文件 :

  1. using Microsoft.AspNetCore.SignalR;
  2. using System.Threading.Tasks;
  3. namespace SignalRChat.Hubs
  4. {
  5. public class ChatHub : Hub
  6. {
  7. public async Task SendMessage(string user, string message)
  8. {
  9. await Clients.All.SendAsync("ReceiveMessage", user, message);
  10. }
  11. }
  12. }

ChatHub 类继承自 SignalR Hub 类。Hub 类管理连接、组和消息。

可通过已连接客户端调用 SendMessage,以向所有客户端发送消息。本教程后面部分将显示调用该方法的 JavaScript 客户端代码。SignalR 代码是异步模式,可提供最大的可伸缩性。

配置 SignalRConfigure SignalR

必须配置 SignalR 服务器,以将 SignalR 请求传递到 SignalR。

  • 将以下突出显示的代码添加到 Startup.cs 文件 。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Microsoft.AspNetCore.Builder;
  6. using Microsoft.AspNetCore.Hosting;
  7. using Microsoft.AspNetCore.HttpsPolicy;
  8. using Microsoft.Extensions.Configuration;
  9. using Microsoft.Extensions.DependencyInjection;
  10. using Microsoft.Extensions.Hosting;
  11. using SignalRChat.Hubs;
  12. namespace SignalRChat
  13. {
  14. public class Startup
  15. {
  16. public Startup(IConfiguration configuration)
  17. {
  18. Configuration = configuration;
  19. }
  20. public IConfiguration Configuration { get; }
  21. // This method gets called by the runtime. Use this method to add services to the container.
  22. public void ConfigureServices(IServiceCollection services)
  23. {
  24. services.AddRazorPages();
  25. services.AddSignalR();
  26. }
  27. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  28. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  29. {
  30. if (env.IsDevelopment())
  31. {
  32. app.UseDeveloperExceptionPage();
  33. }
  34. else
  35. {
  36. app.UseExceptionHandler("/Error");
  37. // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
  38. app.UseHsts();
  39. }
  40. app.UseHttpsRedirection();
  41. app.UseStaticFiles();
  42. app.UseRouting();
  43. app.UseAuthorization();
  44. app.UseEndpoints(endpoints =>
  45. {
  46. endpoints.MapRazorPages();
  47. endpoints.MapHub<ChatHub>("/chatHub");
  48. });
  49. }
  50. }
  51. }

这些更改将 SignalR 添加到 ASP.NET Core 依赖关系注入和路由系统。

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

  • 使用以下代码替换 Pages\Index.cshtml 中的内容 :
  1. @page
  2. <div class="container">
  3. <div class="row">&nbsp;</div>
  4. <div class="row">
  5. <div class="col-2">User</div>
  6. <div class="col-4"><input type="text" id="userInput" /></div>
  7. </div>
  8. <div class="row">
  9. <div class="col-2">Message</div>
  10. <div class="col-4"><input type="text" id="messageInput" /></div>
  11. </div>
  12. <div class="row">&nbsp;</div>
  13. <div class="row">
  14. <div class="col-6">
  15. <input type="button" id="sendButton" value="Send Message" />
  16. </div>
  17. </div>
  18. </div>
  19. <div class="row">
  20. <div class="col-12">
  21. <hr />
  22. </div>
  23. </div>
  24. <div class="row">
  25. <div class="col-6">
  26. <ul id="messagesList"></ul>
  27. </div>
  28. </div>
  29. <script src="~/js/signalr/dist/browser/signalr.js"></script>
  30. <script src="~/js/chat.js"></script>

前面的代码:

  • 创建名称以及消息文本的文本框和“提交”按钮。
  • 使用 id="messagesList" 创建一个列表,用于显示从 SignalR 中心接收的消息。
  • 包含对 SignalR 的脚本引用以及在下一步中创建的 chat.js 应用程序代码 。
    • 在 wwwroot/js 文件夹中,使用以下代码创建 chat.js 文件 :
  1. "use strict";
  2. var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
  3. //Disable send button until connection is established
  4. document.getElementById("sendButton").disabled = true;
  5. connection.on("ReceiveMessage", function (user, message) {
  6. var msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  7. var encodedMsg = user + " says " + msg;
  8. var li = document.createElement("li");
  9. li.textContent = encodedMsg;
  10. document.getElementById("messagesList").appendChild(li);
  11. });
  12. connection.start().then(function () {
  13. document.getElementById("sendButton").disabled = false;
  14. }).catch(function (err) {
  15. return console.error(err.toString());
  16. });
  17. document.getElementById("sendButton").addEventListener("click", function (event) {
  18. var user = document.getElementById("userInput").value;
  19. var message = document.getElementById("messageInput").value;
  20. connection.invoke("SendMessage", user, message).catch(function (err) {
  21. return console.error(err.toString());
  22. });
  23. event.preventDefault();
  24. });

前面的代码:

  • 创建并启动连接。
  • 向“提交”按钮添加一个用于向中心发送消息的处理程序。
  • 向连接对象添加一个用于从中心接收消息并将其添加到列表的处理程序。

运行应用Run the app

  • 按 Ctrl+F5 可运行应用而不进行调试 。
  • 在集成终端中,运行以下命令:
  1. dotnet watch run -p SignalRChat.csproj
  • 从菜单中选择“运行”>“开始执行(不调试)” 。
  • 从地址栏复制 URL,打开另一个浏览器实例或选项卡,并在地址栏中粘贴该 URL。

  • 选择任一浏览器,输入名称和消息,然后选择“发送消息”按钮 。

两个页面上立即显示名称和消息。

SignalR 示例应用

提示

  • 如果应用不起作用,请打开浏览器开发人员工具 (F12) 并转到控制台。可能会看到与 HTML 和 JavaScript 代码相关的错误。例如,假设将 signalr.js 放在不同于系统指示的文件夹中 。在这种情况下,对该文件的引用将不起作用,并且你将在控制台中看到 404 错误。未找到 signalr.js 错误

  • 如果 Chrome 中出现 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY 错误,请运行这些命令以更新开发证书:

  1. dotnet dev-certs https --clean
  2. dotnet dev-certs https --trust

本教程介绍生成使用 SignalR 的实时应用的基础知识。您将学习如何:

  • 创建 Web 项目。
  • 添加 SignalR 客户端库。
  • 创建 SignalR 中心。
  • 配置项目以使用 SignalR。
  • 添加可将消息从任何客户端发送到所有连接客户端的代码。最终将创建一个正常运行的聊天应用:SignalR 示例应用

先决条件Prerequisites

警告

如果使用 Visual Studio 2017,请参阅 dotnet/sdk 问题 #3124,以了解无法与 Visual Studio 一起使用的 .NET Core SDK 版本的信息。

Visual Studio Code 说明使用用于 ASP.NET Core 的 .NET Core CLI 开发功能,如项目创建。可在任何平台(macOS、Linux 或 Windows)上或在任何代码编辑器中遵循这些说明。如果使用 Visual Studio Code 以外的其他内容,则可能需要进行少量更改。

创建 Web 项目Create a web project

  • 从菜单中选择“文件”>“新建项目” 。

  • 在“新建项目”对话框中,选择“已安装”>“Visual C#”>“Web”>“ASP.NET Core Web 应用” 。将项目命名为“SignalRChat” 。

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

  • 选择“Web 应用”,以创建使用 Razor Pages 的项目 。

  • 选择“.NET Core”目标框架,选择“ASP.NET Core 2.2”,然后单击“确定” 。

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

  • 在将要在其中创建新项目文件夹的文件夹中打开集成终端

  • 运行以下命令:

  1. dotnet new webapp -o SignalRChat
  2. code -r SignalRChat
  • 从菜单中选择“文件”>“新建解决方案” 。

  • 选择“.NET Core”>“应用”>“ASP.NET Core Web 应用”(请勿选择 ASP.NET Core Web 应用 (MVC)) 。

  • 选择“下一步” 。

  • 将项目命名为“SignalRChat”,然后选择“创建” 。

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

Microsoft.AspNetCore.App 元包中包括 SignalR 服务器库。JavaScript 客户端库不会自动包含在项目中。对于此教程,使用库管理器 (LibMan) 从 unpkg 获取客户端库。unpkg 是一个内容分发网络 (CDN),可以分发在 npm(即 Node.js 包管理器)中找到的任何内容。

  • 在“解决方案资源管理器”中,右键单击项目,然后选择“添加”>“客户端库” 。

  • 在“添加客户端库” 对话框中,对于“提供程序” ,选择“unpkg” 。

  • 对于“库” ,输入 @microsoft/signalr@3,然后选择不是预览版的最新版本。

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

  • 选择“选择特定文件” ,展开“dist/browser” 文件夹,然后选择“signalr.js” 和“signalr.min.js” 。

  • 将“目标位置” 设置为 wwwroot/lib/signalr/ ,然后选择“安装” 。

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

LibMan 创建 wwwroot/lib/signalr 文件夹并将所选文件复制到该文件夹。

  • 在集成终端中,运行以下命令以安装 LibMan。
  1. dotnet tool install -g Microsoft.Web.LibraryManager.Cli
  • 使用 LibMan 运行以下命令,以获取 SignalR 客户端库。可能需要等待几秒钟的时间才能看到输出。
  1. libman install @microsoft/signalr -p unpkg -d wwwroot/lib/signalr --files dist/browser/signalr.js --files dist/browser/signalr.min.js

参数指定以下选项:

  • 使用 unpkg 提供程序。
  • 将文件复制到 wwwroot/lib/signalr 目标。
  • 仅复制指定的文件。
    输出如下所示:
  1. wwwroot/lib/signalr/dist/browser/signalr.js written to disk
  2. wwwroot/lib/signalr/dist/browser/signalr.min.js written to disk
  3. Installed library "@microsoft/signalr@3.0.1" to "wwwroot/lib/signalr"
  • 在“终端” 中,运行以下命令以安装 LibMan。
  1. dotnet tool install -g Microsoft.Web.LibraryManager.Cli
  • 导航到项目文件夹(包含 SignalRChat.csproj 文件的文件夹)。

  • 使用 LibMan 运行以下命令,以获取 SignalR 客户端库。

  1. libman install @microsoft/signalr -p unpkg -d wwwroot/lib/signalr --files dist/browser/signalr.js --files dist/browser/signalr.min.js

参数指定以下选项:

  • 使用 unpkg 提供程序。
  • 将文件复制到 wwwroot/lib/signalr 目标。
  • 仅复制指定的文件。
    输出如下所示:
  1. wwwroot/lib/signalr/dist/browser/signalr.js written to disk
  2. wwwroot/lib/signalr/dist/browser/signalr.min.js written to disk
  3. Installed library "@microsoft/signalr@3.x.x" to "wwwroot/lib/signalr"

创建 SignalR 中心Create a SignalR hub

中心是一个类,用作处理客户端 - 服务器通信的高级管道。

  • 在 SignalRChat 项目文件夹中,创建 Hubs 文件夹 。

  • 在 Hubs 文件夹中,使用以下代码创建 ChatHub.cs 文件 :

  1. using Microsoft.AspNetCore.SignalR;
  2. using System.Threading.Tasks;
  3. namespace SignalRChat.Hubs
  4. {
  5. public class ChatHub : Hub
  6. {
  7. public async Task SendMessage(string user, string message)
  8. {
  9. await Clients.All.SendAsync("ReceiveMessage", user, message);
  10. }
  11. }
  12. }

ChatHub 类继承自 SignalR Hub 类。Hub 类管理连接、组和消息。

可通过已连接客户端调用 SendMessage,以向所有客户端发送消息。本教程后面部分将显示调用该方法的 JavaScript 客户端代码。SignalR 代码是异步模式,可提供最大的可伸缩性。

配置 SignalRConfigure SignalR

必须配置 SignalR 服务器,以将 SignalR 请求传递到 SignalR。

  • 将以下突出显示的代码添加到 Startup.cs 文件 。
  1. using Microsoft.AspNetCore.Builder;
  2. using Microsoft.AspNetCore.Hosting;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.Extensions.Configuration;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using SignalRChat.Hubs;
  8. namespace SignalRChat
  9. {
  10. public class Startup
  11. {
  12. public Startup(IConfiguration configuration)
  13. {
  14. Configuration = configuration;
  15. }
  16. public IConfiguration Configuration { get; }
  17. // This method gets called by the runtime. Use this method to add services to the container.
  18. public void ConfigureServices(IServiceCollection services)
  19. {
  20. services.Configure<CookiePolicyOptions>(options =>
  21. {
  22. // This lambda determines whether user consent for non-essential cookies is needed for a given request.
  23. options.CheckConsentNeeded = context => true;
  24. options.MinimumSameSitePolicy = SameSiteMode.None;
  25. });
  26. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  27. services.AddSignalR();
  28. }
  29. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  30. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  31. {
  32. if (env.IsDevelopment())
  33. {
  34. app.UseDeveloperExceptionPage();
  35. }
  36. else
  37. {
  38. app.UseExceptionHandler("/Error");
  39. app.UseHsts();
  40. }
  41. app.UseHttpsRedirection();
  42. app.UseStaticFiles();
  43. app.UseCookiePolicy();
  44. app.UseSignalR(routes =>
  45. {
  46. routes.MapHub<ChatHub>("/chatHub");
  47. });
  48. app.UseMvc();
  49. }
  50. }
  51. }

这些更改将 SignalR 添加到 ASP.NET Core 依赖关系注入系统和中间件管道。

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

  • 使用以下代码替换 Pages\Index.cshtml 中的内容 :
  1. @page
  2. <div class="container">
  3. <div class="row">&nbsp;</div>
  4. <div class="row">
  5. <div class="col-6">&nbsp;</div>
  6. <div class="col-6">
  7. User..........<input type="text" id="userInput" />
  8. <br />
  9. Message...<input type="text" id="messageInput" />
  10. <input type="button" id="sendButton" value="Send Message" />
  11. </div>
  12. </div>
  13. <div class="row">
  14. <div class="col-12">
  15. <hr />
  16. </div>
  17. </div>
  18. <div class="row">
  19. <div class="col-6">&nbsp;</div>
  20. <div class="col-6">
  21. <ul id="messagesList"></ul>
  22. </div>
  23. </div>
  24. </div>
  25. <script src="~/lib/signalr/dist/browser/signalr.js"></script>
  26. <script src="~/js/chat.js"></script>

前面的代码:

  • 创建名称以及消息文本的文本框和“提交”按钮。
  • 使用 id="messagesList" 创建一个列表,用于显示从 SignalR 中心接收的消息。
  • 包含对 SignalR 的脚本引用以及在下一步中创建的 chat.js 应用程序代码 。
    • 在 wwwroot/js 文件夹中,使用以下代码创建 chat.js 文件 :
  1. "use strict";
  2. var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
  3. //Disable send button until connection is established
  4. document.getElementById("sendButton").disabled = true;
  5. connection.on("ReceiveMessage", function (user, message) {
  6. var msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  7. var encodedMsg = user + " says " + msg;
  8. var li = document.createElement("li");
  9. li.textContent = encodedMsg;
  10. document.getElementById("messagesList").appendChild(li);
  11. });
  12. connection.start().then(function(){
  13. document.getElementById("sendButton").disabled = false;
  14. }).catch(function (err) {
  15. return console.error(err.toString());
  16. });
  17. document.getElementById("sendButton").addEventListener("click", function (event) {
  18. var user = document.getElementById("userInput").value;
  19. var message = document.getElementById("messageInput").value;
  20. connection.invoke("SendMessage", user, message).catch(function (err) {
  21. return console.error(err.toString());
  22. });
  23. event.preventDefault();
  24. });

前面的代码:

  • 创建并启动连接。
  • 向“提交”按钮添加一个用于向中心发送消息的处理程序。
  • 向连接对象添加一个用于从中心接收消息并将其添加到列表的处理程序。

运行应用Run the app

  • 按 Ctrl+F5 可运行应用而不进行调试 。
  • 在集成终端中,运行以下命令:
  1. dotnet run -p SignalRChat.csproj
  • 从菜单中选择“运行”>“开始执行(不调试)” 。
  • 从地址栏复制 URL,打开另一个浏览器实例或选项卡,并在地址栏中粘贴该 URL。

  • 选择任一浏览器,输入名称和消息,然后选择“发送消息”按钮 。

两个页面上立即显示名称和消息。

SignalR 示例应用

提示

如果应用不起作用,请打开浏览器开发人员工具 (F12) 并转到控制台。可能会看到与 HTML 和 JavaScript 代码相关的错误。例如,假设将 signalr.js 放在不同于系统指示的文件夹中 。在这种情况下,对该文件的引用将不起作用,并且你将在控制台中看到 404 错误。未找到 signalr.js 错误

其他资源Additional resources