教學課程:開始使用 ASP.NET Core SignalR

本教學課程會教導使用 SignalR 建置即時應用程式的基本概念。 您會了解如何:

  • 建立 Web 專案。
  • SignalR新增用戶端程式庫。
  • 建立中 SignalR 樞。
  • 將專案設定為使用 SignalR 。
  • 新增程式碼,以將訊息從任何用戶端傳送至所有連線的用戶端。

最後,您會有一個運作正常的聊天應用程式:

SignalR sample app

必要條件

建立 Web 應用程式專案

  1. 啟動 Visual Studio 2022,然後選取 [建立新專案]。

    Create a new project from the start window

  2. 在 [ 建立新專案 ] 對話方塊中,選取 [ASP.NET Core Web 應用程式],然後選取 [ 下一步]。

    Create an ASP.NET Core Web App

  3. 在 [ 設定新專案] 對話方塊中,輸入 SignalRChat[專案名稱]。 請務必將專案SignalR命名為 Chat,包括比對大寫,因此當您複製並貼上範例程式碼時,命名空間將會相符。

  4. 選取 [下一步] 。

  5. 在 [ 其他資訊] 對話方塊中,選取 [.NET 6.0 (長期支援) ],然後選取 [ 建立]。

    Additional information

SignalR新增用戶端程式庫

伺服器 SignalR 程式庫包含在 ASP.NET Core 共用架構中。 JavaScript 用戶端程式庫不會自動包括在專案中。 在本教學課程中,請使用程式庫管理員 (LibMan) 從 unpkg取得用戶端程式庫。 unpkgnpm上所有專案的快速全域內容傳遞網路。

  • 在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [新增]>[用戶端程式庫]
  • 在 [ 新增Client-Side程式庫 ] 對話方塊中:
    • 針對提供者選取unpkg
    • 針對[程式庫] 輸入 @microsoft/signalr@latest
    • 選取 [選擇特定檔案]、展開 dist/browser 資料夾,然後選取 signalr.jssignalr.min.js
    • [目標位置] 設定為 wwwroot/js/signalr/
    • 選取 [安裝]

Add Client-Side Library dialog - select library

LibMan 會建立 wwwroot/js/signalr 資料夾,並將選取的檔案複製到其中。

建立中 SignalR 樞

中樞類別可提供作為高階管線,用來處理用戶端/伺服器通訊。

  • 在 [ SignalR 聊天專案] 資料夾中,建立 Hubs 資料夾。
  • Hubs 資料夾中,使用下列程式碼建立 ChatHub 類別:
using Microsoft.AspNetCore.SignalR;

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 。 將下列醒目提示的程式碼新增至 Program.cs 檔案。

using SignalRChat.Hubs;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();
app.MapHub<ChatHub>("/chatHub");

app.Run();

上述醒目提示的程式碼會新增 SignalR 至 ASP.NET Core 相依性插入和路由系統。

新增 SignalR 用戶端程式代碼

  • 將 中 Pages/Index.cshtml 的內容取代為下列程式碼:

    @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>
    

    上述標記:

    • 建立文字方塊和提交按鈕。
    • 使用 建立清單 id="messagesList" ,以顯示從中樞接收的 SignalR 訊息。
    • 在下一個步驟中會建立和應用程式程式碼的腳本參考 SignalRchat.js
  • wwwroot/js 資料夾中,使用下列程式碼建立 chat.js 檔案:

    "use strict";
    
    var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
    
    //Disable the send button until connection is established.
    document.getElementById("sendButton").disabled = true;
    
    connection.on("ReceiveMessage", function (user, message) {
        var li = document.createElement("li");
        document.getElementById("messagesList").appendChild(li);
        // We can assign user-supplied strings to an element's textContent because it
        // is not interpreted as markup. If you're assigning in any other way, you 
        // should be aware of possible script injection concerns.
        li.textContent = `${user} says ${message}`;
    });
    
    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();
    });
    

    上述 JavaScript:

    • 建立並啟動連線。
    • 新增處理常式至提交按鈕,以將訊息傳送至中樞。
    • 新增處理常式至連線物件,以從中樞接收訊息,並將它們新增至清單。

執行應用程式

  • CTRL+F5 即可執行應用程式而不偵錯。
  • 從網址列複製 URL,開啟另一個瀏覽器執行個體或索引標籤,然後將 URL 貼入網址列。
  • 選擇任一個瀏覽器,輸入名稱和訊息,然後選取 [傳送訊息] 按鈕。 名稱和訊息會立即顯示在兩個頁面上。

SignalR sample app

提示

  • 如果應用程式無法運作,請開啟您的瀏覽器開發人員工具 (F12),然後移至主控台。 您可能會看到與 HTML 和 JavaScript 程式碼相關的錯誤。 例如,假設您放入 signalr.js 與導向不同的資料夾。 在此情況下,該檔案的參考無法運作,您會在主控台中看到 404 錯誤。 signalr.js not found error

  • 如果您在 Chrome 中收到錯誤ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY,請執行下列命令來更新您的開發憑證:

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

發佈至 Azure

如需部署至 Azure 的資訊,請參閱 快速入門:部署 ASP.NET Web 應用程式

本教學課程說明如何使用 SignalR 建置即時應用程式的基本概念。 您會了解如何:

  • 建立 Web 專案。
  • SignalR新增用戶端程式庫。
  • 建立中 SignalR 樞。
  • 將專案設定為使用 SignalR 。
  • 新增程式碼,以將訊息從任何用戶端傳送至所有連線的用戶端。

最後,您會有一個運作正常的聊天應用程式:

SignalR sample app

必要條件

建立 Web 應用程式專案

  • 從功能表中,選取 [ 檔案 > 新增專案]。
  • 在 [建立新專案] 對話方塊中,選取 [ASP.NET Core Web 應用程式],然後選取 [下一步]
  • 在 [設定您的新專案] 對話方塊中,將專案SignalR 命名為 [聊天],然後選取 [建立]。
  • [建立新的 ASP.NET Core Web 應用程式 ] 對話方塊中,選取 [.NET Core ] 並 ASP.NET Core 3.1
  • 選取 [Web 應用程式 ] 以建立使用 Razor Pages 的專案,然後選取 [ 建立]。

New Project dialog in Visual Studio

SignalR新增用戶端程式庫

伺服器 SignalR 程式庫包含在 ASP.NET Core 3.1 共用架構中。 JavaScript 用戶端程式庫不會自動包括在專案中。 針對此教學課程,您會使用程式庫管理員 (LibMan) 從 unpkg 取得用戶端程式庫。 unpkg 是一種內容傳遞網路 (CDN) ,可傳遞 npm 中Node.js套件管理員中找到的任何專案。

  • 在 [方案總管] 中,以滑鼠右鍵按一下專案,然後選取 [新增]>[用戶端程式庫]
  • 在 [新增用戶端程式庫] 對話方塊中,針對 [提供者] 選取 [unpkg]
  • 針對 [程式庫] 輸入 @microsoft/signalr@latest
  • 選取 [選擇特定檔案]、展開 dist/browser 資料夾,然後選取 signalr.jssignalr.min.js
  • [目標位置 ] 設定為 wwwroot/js/signalr/
  • 選取 [安裝]

Add Client-Side Library dialog - select library

LibMan 會建立 wwwroot/js/signalr 資料夾,並將選取的檔案複製到其中。

建立中 SignalR 樞

中樞類別可提供作為高階管線,用來處理用戶端/伺服器通訊。

  • 在 [ SignalR 聊天專案] 資料夾中,建立 Hubs 資料夾。
  • Hubs 資料夾中,使用下列程式碼建立 ChatHub.cs 檔案:
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 檔案。

    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 核心相依性插入和路由系統。

新增 SignalR 用戶端程式代碼

  • 將 中 Pages/Index.cshtml 的內容取代為下列程式碼:

    @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>
    

    上述程式碼:

    • 建立名稱和訊息文字的文字方塊,以及提交按鈕。
    • 使用 建立清單 id="messagesList" ,以顯示從中樞接收的 SignalR 訊息。
    • 包含 的 SignalR 腳本參考,以及 chat.js 您在下一個步驟中建立的應用程式程式碼。
  • wwwroot/js 資料夾中,使用下列程式碼建立 chat.js 檔案:

    "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 li = document.createElement("li");
        document.getElementById("messagesList").appendChild(li);
        // We can assign user-supplied strings to an element's textContent because it
        // is not interpreted as markup. If you're assigning in any other way, you 
        // should be aware of possible script injection concerns.
        li.textContent = `${user} says ${message}`;
    });
    
    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 貼入網址列。
  • 選擇任一個瀏覽器,輸入名稱和訊息,然後選取 [傳送訊息] 按鈕。 名稱和訊息會立即顯示在兩個頁面上。

SignalR sample app

提示

  • 如果應用程式無法運作,請開啟您的瀏覽器開發人員工具 (F12),然後移至主控台。 您可能會看到與 HTML 和 JavaScript 程式碼相關的錯誤。 例如,假設您放入 signalr.js 與導向不同的資料夾。 在此情況下,該檔案的參考無法運作,您會在主控台中看到 404 錯誤。 signalr.js not found error

  • 如果您在 Chrome 中收到錯誤ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY,請執行下列命令來更新您的開發憑證:

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

發佈至 Azure

如需部署至 Azure 的資訊,請參閱 快速入門:部署 ASP.NET Web 應用程式