本教程介绍使用 SignalR 生成实时应用的基础知识。 您将学习如何:
- 创建 Web 项目。
- 添加 SignalR 客户端库。
- 创建 SignalR 中心。
- 配置项目以使用 SignalR。
- 添加可将消息从任何客户端发送到所有连接客户端的代码。
最后,你将拥有一个工作聊天应用:
先决条件
- 已安装“ASP.NET 和 Web 开发”工作负载的 Visual Studio 2017 版本 15.9 或更高版本。 可使用 Visual Studio 2019,但某些项目创建步骤不同于本教程中所示的内容。
- .NET Core SDK 2.2 或更高版本
警告
如果使用 Visual Studio 2017,请参阅 dotnet/sdk 问题 #3124,以了解无法与 Visual Studio 一起使用的 .NET Core SDK 版本的信息。
创建 Web 项目
-
从菜单中选择“文件”>“新建项目”。
-
在“新建项目”对话框中,选择“已安装”>“Visual C#”>“Web”>“ASP.NET Core Web 应用” 。 将项目命名为“SignalRChat”。
-
选择“Web 应用”,以创建使用 Razor Pages 的项目。
-
选择“.NET Core”目标框架,选择“ASP.NET Core 2.2”,然后单击“确定” 。
添加 SignalR 客户端库
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 文件夹并将所选文件复制到该文件夹。
创建 SignalR 中心
中心是一个类,用作处理客户端 - 服务器通信的高级管道。
-
在 SignalRChat 项目文件夹中,创建 Hubs 文件夹。
-
在 Hubs 文件夹中,使用以下代码创建 ChatHub.cs 文件 :
C#复制
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类继承自 SignalRHub类。Hub类管理连接、组和消息。可通过已连接客户端调用
SendMessage,以向所有客户端发送消息。 本教程后面部分将显示调用该方法的 JavaScript 客户端代码。 SignalR 代码是异步模式,可提供最大的可伸缩性。
配置 SignalR
必须将 SignalR 服务器配置为将 SignalR 请求传递给 SignalR。
-
将以下突出显示的代码添加到 Startup.cs 文件。
C#复制
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 依赖关系注入系统和中间件管道。
添加 SignalR 客户端代码
-
使用以下代码替换 Pages\Index.cshtml 中的内容:
CSHTML复制
@page <div class="container"> <div class="row"> </div> <div class="row"> <div class="col-6"> </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"> </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>前面的代码:
- 创建名称以及消息文本的文本框和“提交”按钮。
- 使用
id="messagesList"创建一个列表,用于显示从 SignalR 中心接收的消息。 - 包含对 SignalR 的脚本引用以及在下一步中创建的“chat.js”应用程序代码。
-
在 wwwroot/js 文件夹中,使用以下代码创建 chat.js 文件 :
JavaScript复制
"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, "&").replace(/</g, "<").replace(/>/g, ">"); 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(); });前面的代码:
- 创建并启动连接。
- 向“提交”按钮添加一个用于向中心发送消息的处理程序。
- 向连接对象添加一个用于从中心接收消息并将其添加到列表的处理程序。
运行应用
- 按 Ctrl+F5 可运行应用而不进行调试。
-
从地址栏复制 URL,打开另一个浏览器实例或选项卡,并在地址栏中粘贴该 URL。
-
选择任一浏览器,输入名称和消息,然后选择“发送消息”按钮。
两个页面上立即显示名称和消息。
提示
如果应用不起作用,请打开浏览器开发人员工具 (F12) 并转到控制台。 可能会看到与 HTML 和 JavaScript 代码相关的错误。 例如,假设将 signalr.js 放在不同于系统指示的文件夹中。 在这种情况下,对该文件的引用将不起作用,并且你将在控制台中看到 404 错误。