前言

在接下來的章節將會對兩種 Bloazr 的專案範本做解說,分別是 Blazor Server 以及 Blazor WebAssembly,其中 WebAssembly 會介紹獨立(Standalone) Blazor WebAssembly 和裝載(Hosted) Blazor WebAssembly。

環境

Blazor Server 專案建立

  1. 首先開啟 Visual Studio 2022,找到 Blazor Server 應用程式

Visual Studio 2022 選取Blazor Server 應用程式

  1. 專案建立完成後點擊最上方長得像播放按鈕的開始偵錯,就可以進行編譯讓專案跑起來

Visual Studio 2022  偵錯按鈕位置

在 .Net 6 預設是使用 Kestrel 啟動,而不是過去的 IIS

  1. 建置完成就會看見熟悉的 Hello World!
  • Home

Blazor 首頁

  • Counter

Blazor Counter頁面

  • FetchData

Blazor FetchData頁面

專案結構

接下來我們將目光移到VS內的方案總管

專案資料夾

這邊分成五大區塊來做說明

1. Properties

在這個資料夾內有 LaunchSettings.json 檔案,用來提供VS執行應用程式時所要套用的組態設定 LaunchSettings 檔案內容

2. wwwroot

用來放靜態資產檔案的資料夾 wwwroot 資料夾

3. Data

Data 資料夾 可以看見內部有兩個檔案

  • WeatherForecast.cs 提供FetchData元件的資料類別
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 public class WeatherForecast
    {
        public DateTime Date { get; set; }

        public int TemperatureC { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

        public string? Summary { get; set; }
    }
  • WeatherForecastService.cs 提供FetchData元件Fetch資料的實作
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    public class WeatherForecastService
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
        {
            return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = startDate.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            }).ToArray());
        }
    }
}

4. Pages

用來放置可供路由的元件或頁面(.razor)

Pages 資料夾

  • _Host.cshtml 是Blazor的根頁面(Root Page),App 元件會解析在這邊
  • _Layout.cshtml 是 _Host.cshtml 的版面配置頁,Blazor Server 的 head 內容此檔案內
  • Counter 元件,實作計數器頁面
  • Error 元件,實作例外頁面
  • FetchData 元件,實作資料擷取頁
  • Index 元件,實作首頁

5. Shard

放置共用元件和樣式

  • MainLayout 元件,應用程式的版面配置元件
  • NavMenu 元件,Navbar的樣式表單
  • SurveyPrompt 元件,問卷元件

6. Other

剩下的是沒有在資料夾內的檔案

其他檔案

  • _Imports 元件,內部會放要放入元件內的指示詞,像是 @using
  • App 元件,應用程式的根元件
  • appsetting.json 專案的設定檔
  • Program.cs .net Core 應用程式的進入點,在這邊做DI註冊、Middleware的處理等等

運作方式

Blazor Server 是依靠 SignalR 機制讓伺服端與客戶端進行雙向溝通,在瀏覽器開啟 Blazor 網頁時,客戶端會自動與伺服端建立SignalR連線。

瀏覽器端的Console Signal連線

在Console中看見負責處理SignalR的檔案是blazor.server.js

心跳包截圖

雙方透過每隔一段時間就會透過心跳包(Heartbeat)機制確保連線

當我切換到Counter頁面,並且點擊Click Me按鈕觸發 UI 更新時,會重新轉譯元件圖形,計算UI Diff(差異) 後以二進位的方式傳送至瀏覽器套用進行畫面的更新

透過SignalR的連線處理 JavaScript Interop 呼叫

  • 從 JavaScript 呼叫 .NET(BeginInvokeDotNetFromJs) 發送事件到伺服端

BeginInvokeDotNetFromJs

  • 從 .NET 呼叫 JavaScript (JS.RenderBatch) 伺服端回應進行畫面渲染

JS.RenderBatch

  • 從 JavaScript 呼叫 .NET(OnRenderCompleted) 通知伺服端畫面渲染完成

OnRenderCompleted

  • 從 .NET 呼叫 JavaScript (JS.EndInvokeDotNet) 完成非同步呼叫

JS.EndInvokeDotNet

關於 JavaScript Interop 我以後也會專門寫文章跟大家探討XD

小結

理解了 Blazor Server 運作的原理後,可以總結出幾項優缺點

優點

  1. 載入的速度快
  2. 程式碼不會被傳送到Client端,安全性較佳
  3. 瀏覽器的支援性較佳
  4. 完整的 .NET API

缺點

  1. 所有的UI互動都通過與伺服器交互,可能會導致延遲感較明顯
  2. 無法使用無伺服器(Serverless)部署

伺服器的記憶體在高負載時可能會是最早耗盡的,一個SignalR線路大概使用250KB的記憶體 根據微軟提供的基準,如果要提供5000名使用者,記憶體至少需要預留1.3GB以上

下一篇文章介紹 Blazor WebAssembly 的專案建置