搭配 HttpClient 使用 HTTP/3

HTTP/3 是第三個且最近標準化的 HTTP 主要版本。 HTTP/3 所使用的語意與 HTTP/1.1 和 HTTP/2 相同:相同的要求方法、狀態碼和訊息欄位適用於所有版本。 差異在於基礎傳輸方式。 HTTP/1.1 和 HTTP/2 都使用 TCP 來做傳輸。 HTTP/3 使用的則是與 HTTP/3 一起開發的傳輸技術,名為 QUIC

相較於 HTTP/1.1 和 HTTP/2,HTTP/3 和 QUIC 都有幾個優點:

  • 第一個要求的回應時間更快。 QUIC 和 HTTP/3 在用戶端與伺服器之間協商連線所需的來回行程較少。 第一個要求更快抵達伺服器。
  • 改善了連線封包遺失時的體驗。 HTTP/2 會透過一個 TCP 連線多工處理多個要求。 連線的封包遺失會影響所有要求。 此問題稱為「隊頭阻塞」。 由於 QUIC 提供原生的多工處理功能,因此封包遺失只會影響到遺失資料的要求。
  • 支援在網路之間轉換。 此功能適用於行動裝置,因為行動裝置變更位置時,通常會在 WIFI 和行動數據網路之間切換。 目前,HTTP/1.1 和 HTTP/2 連線在切換網路時會發生錯誤。 應用程式或網頁瀏覽器必須重試所有失敗的 HTTP 要求。 HTTP/3 可讓應用程式或網頁瀏覽器在網路變更時平順地繼續執行。 在 .NET 7 中,HttpClient 和 Kestrel 不支援網路轉換。 未來的版本可能會提供此支援。

重要

設定來使用 HTTP/3 的應用程式也應該支援 HTTP/1.1 和 HTTP/2。 如果在 HTTP/3 中發現問題,建議您停用 HTTP/3,直到該問題在未來的 .NET 版本中解決為止。

HttpClient 設定

您可以將藉由將 HttpRequestMessage.Version 設為 3.0 來設定 HTTP 版本。 不過,由於並非所有路由器、防火牆和 Proxy 都正確支援 HTTP/3,因此建議搭配 HTTP/1.1 和 HTTP/2 來設定 HTTP/3。 在 HttpClient 中,這可以透過指定下列項目來完成:

平台相依性

HTTP/3 使用 QUIC 作為其傳輸通訊協定。 HTTP/3 的 .NET 實作會使用 MsQuic 來提供 QUIC 功能。 因此,HTTP/3 的 .NET 支援取決於 MsQuic 平台需求。 如需如何安裝 MsQuic 的詳細資訊,請參閱 QUIC 平台相依性。 如果執行 HttpClient 的平台不具備 HTTP/3 的所有需求,則會停用該平台。

使用 HttpClient

下列程式碼範例會使用最上層陳述式並示範如何在要求中指定 HTTP3:

// See https://aka.ms/new-console-template for more information
using System.Net;

using var client = new HttpClient
{
    DefaultRequestVersion =  HttpVersion.Version30,
    DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact
};

Console.WriteLine("--- localhost:5001 ---");

HttpResponseMessage resp = await client.GetAsync("https://localhost:5001/");
string body = await resp.Content.ReadAsStringAsync();

Console.WriteLine(
    $"status: {resp.StatusCode}, version: {resp.Version}, " +
    $"body: {body.Substring(0, Math.Min(100, body.Length))}");

.NET 6 中的 HTTP/3 支援

在 .NET 6 中,HTTP/3 可作為預覽功能使用,因為 HTTP/3 規格尚未定案。 .NET 6 的 HTTP/3 中可能有行為或效能問題。 如需預覽功能的詳細資訊,請參閱預覽功能規格

若要在 .NET 6 中啟用 HTTP/3 支援,請在專案檔中包含 RuntimeHostConfigurationOption 節點,以透過 HttpClient 啟用 HTTP/3:

<ItemGroup>
    <RuntimeHostConfigurationOption Value="true"
        Include="System.Net.SocketsHttpHandler.Http3Support" />
</ItemGroup>

或者,您可以用應用程式程式碼呼叫 System.AppContext.SetSwitch,或將 DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP3SUPPORT 環境變數設定為 true。 如需詳細資訊,請參閱 .NET 環境變數:DOTNET_SYSTEM_NET_HTTP_*

要求 HTTP/3 設定旗標,是為了在使用版本原則 RequestVersionOrHigher 時避免應用程式未來發生中斷。 呼叫目前使用 HTTP/1.1 和 HTTP/2 的伺服器時,如果伺服器後來升級為 HTTP/3,用戶端會嘗試使用 HTTP/3,而且因為標準並非最終版本且可能在 .NET 6 發行之後變更,所以可能有不相容問題。

.NET 6 只與 1.9.x 版的 libmsquic 相容。 由於程式庫中的中斷性變更,Libmsquic 2.x 與 .NET 6 不相容。 Libmsquic 會在需要時收到 1.9.x 的更新,以納入安全性修正程式。

HTTP/3 伺服器

可由 ASP.NET 透過 .NET 6 (作為預覽版) 和 .NET 7 (完全支援) 中的 Kestrel 伺服器來支援 HTTP/3。 如需詳細資訊,請參閱透過 ASP.NET Core Kestrel Web 服務器來使用 HTTP/3

公用測試伺服器

Cloudflare 在 https://cloudflare-quic.com 裝載了一個可用來測試用戶端的 HTTP/3 網站。

另請參閱