本教程介紹生成使用 SignalR 的實(shí)時(shí)應(yīng)用的基礎(chǔ)知識(shí)。 您將學(xué)習(xí)如何:
- 創(chuàng)建 Web 項(xiàng)目。
- 添加 SignalR 客戶端庫。
- 創(chuàng)建 SignalR 中心。
- 配置項(xiàng)目以使用 SignalR。
- 添加可將消息從任何客戶端發(fā)送到所有連接客戶端的代碼。
最終將創(chuàng)建一個(gè)正常運(yùn)行的聊天應(yīng)用:
查看或下載示例代碼(如何下載)。
系統(tǒng)必備
創(chuàng)建 Web 項(xiàng)目
從菜單中選擇“文件”>“新建項(xiàng)目”。
在“新建項(xiàng)目”對(duì)話框中,選擇“已安裝”>“Visual C#”>“Web”>“ASP.NET Core Web 應(yīng)用”。 將項(xiàng)目命名為“SignalRChat”。
選擇“Web 應(yīng)用”,以創(chuàng)建使用 Razor Pages 的項(xiàng)目。
選擇“.NET Core”目標(biāo)框架,選擇“ASP.NET Core 2.2”,然后單擊“確定”。
添加 SignalR 客戶端庫
Microsoft.AspNetCore.App 元包中包括 SignalR 服務(wù)器庫。 JavaScript 客戶端庫不會(huì)自動(dòng)包含在項(xiàng)目中。 對(duì)于此教程,使用庫管理器 (LibMan) 從 unpkg 獲取客戶端庫。 unpkg 是一個(gè)內(nèi)容分發(fā)網(wǎng)絡(luò) (CDN),可以分發(fā)在 npm(即 Node.js 包管理器)中找到的任何內(nèi)容。
在“解決方案資源管理器”中,右鍵單擊項(xiàng)目,然后選擇“添加” > “客戶端庫”。
在“添加客戶端庫”對(duì)話框中,對(duì)于“提供程序”,選擇“unpkg”。
對(duì)于“庫”,輸入 @aspnet/signalr@1
,然后選擇不是預(yù)覽版的最新版本。
選擇“選擇特定文件”,展開“dist/browser”文件夾,然后選擇“signalr.js”和“signalr.min.js”。
將“目標(biāo)位置”設(shè)置為 wwwroot/lib/signalr/,然后選擇“安裝”。
LibMan 創(chuàng)建 wwwroot/lib/signalr 文件夾并將所選文件復(fù)制到該文件夾。
創(chuàng)建 SignalR 中心
中心是一個(gè)類,用作處理客戶端 - 服務(wù)器通信的高級(jí)管道。
- 在 SignalRChat 項(xiàng)目文件夾中,創(chuàng)建 Hubs 文件夾。
- 在 Hubs 文件夾中,使用以下代碼創(chuàng)建 ChatHub.cs 文件:C#復(fù)制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 類。 Hub 類管理連接、組和消息??赏ㄟ^已連接客戶端調(diào)用 SendMessage,以向所有客戶端發(fā)送消息。 本教程后面部分將顯示調(diào)用該方法的 JavaScript 客戶端代碼。 SignalR 代碼是異步模式,可提供最大的可伸縮性。
配置 SignalR
必須配置 SignalR 服務(wù)器,以將 SignalR 請(qǐng)求傳遞到 SignalR。
- 將以下突出顯示的代碼添加到 Startup.cs 文件。C#復(fù)制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 依賴關(guān)系注入系統(tǒng)和中間件管道。
添加 SignalR 客戶端代碼
- 使用以下代碼替換 Pages\Index.cshtml 中的內(nèi)容:CSHTML復(fù)制@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>
前面的代碼:創(chuàng)建名稱以及消息文本的文本框和“提交”按鈕。使用 id="messagesList" 創(chuàng)建一個(gè)列表,用于顯示從 SignalR 中心接收的消息。包含對(duì) SignalR 的腳本引用以及在下一步中創(chuàng)建的 chat.js 應(yīng)用程序代碼。
- 在 wwwroot/js 文件夾中,使用以下代碼創(chuàng)建 chat.js 文件:JavaScript復(fù)制"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();
});
前面的代碼:創(chuàng)建并啟動(dòng)連接。向“提交”按鈕添加一個(gè)用于向中心發(fā)送消息的處理程序。向連接對(duì)象添加一個(gè)用于從中心接收消息并將其添加到列表的處理程序。
運(yùn)行應(yīng)用
- 按 Ctrl+F5 可運(yùn)行應(yīng)用而不進(jìn)行調(diào)試。
- 從地址欄復(fù)制 URL,打開另一個(gè)瀏覽器實(shí)例或選項(xiàng)卡,并在地址欄中粘貼該 URL。
- 選擇任一瀏覽器,輸入名稱和消息,然后選擇“發(fā)送消息”按鈕。兩個(gè)頁面上立即顯示名稱和消息。
提示
如果應(yīng)用不起作用,請(qǐng)打開瀏覽器開發(fā)人員工具 (F12) 并轉(zhuǎn)到控制臺(tái)。 可能會(huì)看到與 HTML 和 JavaScript 代碼相關(guān)的錯(cuò)誤。 例如,假設(shè)將 signalr.js 放在不同于系統(tǒng)指示的文件夾中。 在這種情況下,對(duì)該文件的引用將不起作用,并且你將在控制臺(tái)中看到 404 錯(cuò)誤。
更多建議: