> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MsQuic

> MsQuic

本文說明如何搭配 Microsoft Game Development Kit (GDK) 使用 [MsQuic](https://github.com/microsoft/msquic)。MsQuic 是 Microsoft 對 [IETF QUIC](https://datatracker.ietf.org/wg/quic/about/) 通訊協定的實作。它是跨平台的、以 C 撰寫，並設計為一般用途的 QUIC 程式庫。

QUIC 最初的設計目的是取代使用「TLS over TCP」的案例，例如 HTTP。開發人員將其擴充為一般用途的 UDP 資料傳輸層，適合在單一連線上多工處理即時的不可靠資料包訊息，以及類似 TCP 的可靠資料流。此設計使其特別適合作為用戶端/伺服器傳輸層，以及即時遊戲流量資料流的基礎。

MsQuic 專為 GDK 遊戲量身打造，也適用於多種平台，包括 Windows Server、Linux 桌面與伺服器、iOS、Android 和 macOS。

[MsQuic API 文件](https://github.com/microsoft/msquic/blob/main/docs/API.md)涵蓋許多重要的 MsQuic 概念，並說明如何針對 MsQuic API 介面撰寫程式碼。

## QUIC 功能

* 所有封包都經過加密，且交握會使用 TLS 1.3 進行驗證。
* 可靠與不可靠應用程式資料的平行資料流。
* 在第一次來回行程中交換應用程式資料 (0-RTT)。
* 改良的壅塞控制與遺失復原。
* 用戶端的 IP 位址或連接埠變更後仍可維持連線。
* 無狀態負載平衡。
* 可輕鬆擴充新功能和延伸模組。

## MsQuic 實作

除了專為搭配 GDK 遊戲使用而量身打造之外，MsQuic 還有數項功能，使其有別於其他 QUIC 實作：

* 針對用戶端和伺服器最佳化。
* 針對最大輸送量和最小延遲最佳化。
* 非同步 IO。
* 支援接收端調整 (RSS)。
* 支援 UDP 傳送和接收合併。

MsQuic 實作下列 QUIC RFC：

* [RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000)
* [RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001)
* [RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002)

MsQuic 實作下列 QUIC 草案延伸模組：

* [資料包](https://datatracker.ietf.org/doc/html/draft-ietf-quic-datagram)
* [版本交涉](https://datatracker.ietf.org/doc/html/draft-ietf-quic-version-negotiation)
* [負載平衡](https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers)
* [ACK 頻率](https://datatracker.ietf.org/doc/html/draft-ietf-quic-ack-frequency)
* [效能測試](https://datatracker.ietf.org/doc/html/draft-banks-quic-performance)

## 取得 MsQuic

Microsoft 在開放原始碼 GitHub 存放庫中裝載 MsQuic。您應該透過位於[這裡](https://github.com/microsoft/msquic/blob/main/docs/Release.md)的其中一個正式版本取得 MsQuic。XBOX Series X|S 主機支援是在 prerelease/1.9 中新增的，不過對於 GDK 遊戲，建議您盡可能採用最新的正式發行版本。

您可以在特定版本的 [Assets](https://github.com/microsoft/msquic/releases) 區段中，找到該版本預先建置的 MsQuic 二進位檔。特定 MsQuic 版本的所有建置類別彼此完全相容。雖然 MsQuic 也會盡量維持其版本的回溯相容性，但請參閱 MsQuic 文件和版本資訊，了解不同版本之間的相容性預期。

### 以 GDK 為基礎的 PC 遊戲

針對以 GDK 為基礎的 PC 遊戲，請使用 `msquic_windows_x64_Release_openssl` 預先建置的二進位檔。

PC 上的 GDK 遊戲會以原生 x64 Win32 應用程式的形式執行。請使用針對 x64 平台建置的 MsQuic 版本。在 PC 上，請使用以 OpenSSL 建置的 MsQuic 版本，因為它支援 GDK 所支援的所有作業系統版本。使用 Schannel 的版本僅支援 Windows 11 作業系統及更新版本。

### 以 GDK 為基礎的主機遊戲

針對以 GDK 為基礎的主機遊戲，請使用 `msquic_gamecore_console_x64_Release_schannel` 預先建置的二進位檔。

MsQuic 為 XBOX 主機上以 GDK 為基礎的遊戲提供特殊的建置類別。此類別會將 MsQuic 限制為 `WINAPI_PARTITION_GAMES` 下的 API，並使 MsQuic 連結 `XGamePlatform.lib`。若要使用此建置類別，您必須安裝 2021 年 10 月版本或更新版本的 XGDK。為以 GDK 為基礎的主機遊戲建置時，MsQuic 會使用 Schannel。

<a id="ClientServerAuthentication" />

## 用戶端與伺服器驗證

MsQuic 會自動使用與 HTTPS Web 要求相同的驗證和確認路徑來驗證您的伺服器。用戶端驗證應遵循[安全用戶端/伺服器通訊的最佳做法 (NDA 主題)](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/game-principles/security/communication-security/communication-security-impl/gc-secure-game-mesh-impl#ClientAuthentication) 中所述的最佳做法。

在 MsQuic 中，用戶端和伺服器都應使用 [ConfigurationLoadCredential](https://github.com/microsoft/msquic/blob/main/docs/api/ConfigurationLoadCredential.md) API 搭配適當的 [QUIC\_CREDENTIAL\_CONFIG](https://github.com/microsoft/msquic/blob/main/docs/api/QUIC_CREDENTIAL_CONFIG.md) 來設定您的憑證。MsQuic 中預設包含的所有加密套件都被視為安全，但請務必正確設定 MsQuic 在用戶端和伺服器上驗證憑證的方式，以確保建立安全且經過驗證的通訊通道。

在伺服器上，若要使用 XSTS 權杖用戶端驗證，您應該指定 `QUIC_CREDENTIAL_FLAG_REQUIRE_CLIENT_AUTHENTICATION`、`QUIC_CREDENTIAL_FLAG_INDICATE_CERTIFICATE_RECEIVED` 和 `QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION` 旗標。指定 `QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION` 旗標時，您必須在 [QUIC\_CONNECTION\_EVENT\_PEER\_CERTIFICATE\_RECEIVED](https://github.com/microsoft/msquic/blob/main/docs/api/QUIC_CONNECTION_EVENT.md#quic_connection_event_peer_certificate_received) 事件回呼中自行驗證用戶端憑證，如[安全用戶端/伺服器通訊的最佳做法 (NDA 主題)](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/game-principles/security/communication-security/communication-security-impl/gc-secure-game-mesh-impl#ClientAuthentication) 一節中所述。

此外，在伺服器上，您應該提供具有正確根目錄的憑證，讓用戶端能夠驗證您的伺服器，就像您在 HTTPS Web 伺服器中所做的一樣。

在用戶端上，您\_絕對不\_應該指定 `QUIC_CREDENTIAL_FLAG_NO_CERTIFICATE_VALIDATION` 旗標，因為 MsQuic 用於伺服器驗證的預設行為是驗證身分最簡單且最安全的方式。相反地，對於 XSTS 權杖用戶端驗證，您應該指定 `QUIC_CREDENTIAL_FLAG_CLIENT` 旗標，並搭配由您的伺服器所產生的憑證，如[安全用戶端/伺服器通訊的最佳做法 (NDA 主題)](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/game-principles/security/communication-security/communication-security-impl/gc-secure-game-mesh-impl#ClientAuthentication) 一節中所述。建議您指定 `QUIC_CREDENTIAL_TYPE_CERTIFICATE_CONTEXT` 模式來提供用戶端憑證，並使用 [CertCreateContext](https://learn.microsoft.com/windows/win32/api/wincrypt/nf-wincrypt-certcreatecontext) 等 API，直接從您的 Web 要求回應資料產生內容。

## 網路初始化

MsQuic 不會自動為 GDK 遊戲處理[網路初始化](/zh-TW/build/console-features/networking/initialization-connectivity-networking)。在遊戲啟動後以及每次繼續後，請等待網路完成初始化，再使用 [MsQuicOpenVersion](https://github.com/microsoft/msquic/blob/main/docs/api/MsQuicOpenVersion.md) 或 [MsQuicOpen](https://github.com/microsoft/msquic/blob/main/docs/api/MsQuicOpen.md) 初始化 MsQuic。

<a id="SuspendResume" />

## 暫停與繼續

使用 `RegisterAppStateChangeNotification` 註冊暫停和繼續事件。暫停時，關閉所有開啟的資料流，並關閉 MsQuic。然後在繼續時，等待網路初始化，再重新開啟 MsQuic。

若要在暫停逾時內快速關閉所有 MsQuic 資料流，請針對每個開啟的資料流，使用 `QUIC_STREAM_SHUTDOWN_FLAG_ABORT` 和 `QUIC_STREAM_SHUTDOWN_FLAG_IMMEDIATE` 旗標呼叫 [StreamShutdown](https://github.com/microsoft/msquic/blob/main/docs/api/StreamShutdown.md)。此呼叫會立即觸發 `QUIC_STREAM_EVENT_SHUTDOWN_COMPLETE` 事件。此時，就可以安全地呼叫 [StreamClose](https://github.com/microsoft/msquic/blob/main/docs/api/StreamClose.md) 來關閉資料流。指定連線的所有資料流都關閉後，請使用 `QUIC_CONNECTION_SHUTDOWN_FLAG_SILENT` 旗標呼叫 [ConnectionShutdown](https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionShutdown.md)，接著呼叫 [ConnectionClose](https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionClose.md)。關閉所有連線後，針對任何未處理的註冊和設定呼叫 [RegistrationClose](https://github.com/microsoft/msquic/blob/main/docs/api/RegistrationClose.md) 和 [ConfigurationClose](https://github.com/microsoft/msquic/blob/main/docs/api/ConfigurationClose.md)，接著呼叫 [MsQuicClose](https://github.com/microsoft/msquic/blob/main/docs/api/MsQuicClose.md)。

## 慣用連接埠

在 GDK 遊戲中，請將[慣用本機 UDP 多人遊戲連接埠](/zh-TW/build/console-features/networking/game-mesh/preferred-local-udp-multiplayer-port-networking)用於主要遊戲流量。在呼叫 [ConnectionStart](https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionStart.md) 之前，請在連線物件控制代碼上使用 [SetParam](https://github.com/microsoft/msquic/blob/main/docs/api/SetParam.md) 函式搭配 `QUIC_PARAM_CONN_LOCAL_ADDRESS` 設定，在 MsQuic 中設定此連接埠。

設定 `QUIC_PARAM_CONN_LOCAL_ADDRESS` 時，請指定 `AF_UNSPEC` 系列，以允許雙堆疊 IPv4 和 IPv6 通訊端。下列範例示範當 `MsQuicCallTable` 是從 [MsQuicOpen](https://github.com/microsoft/msquic/blob/main/docs/api/MsQuicOpen.md) 傳回，且 `MsQuicConnectionHandle` 是從 [ConnectionOpen](https://github.com/microsoft/msquic/blob/main/docs/api/ConnectionOpen.md) 傳回時，如何設定慣用連接埠。

```text theme={null}
uint16_t preferredPort;
if (SUCCEEDED(XNetworkingQueryPreferredLocalUdpMultiplayerPort(&preferredPort)))
{
    QUIC_ADDR localAddress = {};
    localAddress.si_family = AF_UNSPEC;
    localAddress.Ipv4.sin_port = htons(preferredPort);

    QUIC_STATUS status = MsQuicCallTable->SetParam(
        MsQuicConnectionHandle,
        QUIC_PARAM_LEVEL_CONNECTION,
        QUIC_PARAM_CONN_LOCAL_ADDRESS,
        sizeof(localAddress),
        &localAddress);
}
```

## 記憶體考量

MsQuic 的高效能實作允許高頻寬資料在您的 GDK 遊戲之間傳輸。作為 [WinSock 記憶體考量](/zh-TW/build/console-features/networking/game-mesh/winsock-intro-networking#SocketMemory)的延伸，使用 MsQuic 時，請遵循下列最佳做法，以盡量減少核心的記憶體耗用量：

GDK 遊戲應將回呼中的任何執行時間降到最低。MsQuic 不會為通訊協定執行和對應用程式的上行呼叫使用個別的執行緒。因此，回呼中的任何顯著延遲都會延遲通訊協定，並增加核心所需的記憶體耗用量。遊戲需要完成的任何大量時間或工作，都必須在其自己的執行緒上進行。

GDK 遊戲應有效率地管理其傳送緩衝區，以減少核心記憶體使用量。如需詳細資訊，請參閱 [MsQuic 中的傳送緩衝處理](https://github.com/microsoft/msquic/blob/main/docs/Streams.md#send-buffering)，了解 MsQuic 如何讓您的遊戲控制此行為。

強烈建議您搭配 MsQuic 使用非同步接收，以確保任何接收的資料都能有效率地傳輸到使用者模式緩衝區。[在 MsQuic 中接收](https://github.com/microsoft/msquic/blob/main/docs/Streams.md#receiving)提供有關如何處理非同步接收的其他詳細資料。此外，請勿在 MsQuic GDK 用戶端中使用部分資料接受功能，以盡量減少耗用的核心記憶體量。

## 另請參閱

[MsQuic](https://github.com/microsoft/msquic)

[MsQuic API 文件](https://github.com/microsoft/msquic/blob/main/docs/API.md)

[MsQuic 版本](https://github.com/microsoft/msquic/blob/main/docs/Release.md)

[建置 MsQuic 文件](https://github.com/microsoft/msquic/blob/main/docs/BUILD.md)

[MsQuic Echo PlayFab 伺服器範例](https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Samples/Live/MsQuicEcho)


## Related topics

- [MsQuic](/build/console-features/networking/game-mesh/msquic-intro-networking.md)
- [Game Mesh](/build/console-features/networking/game-mesh/game-mesh-toc.md)
- [Networking on XBOX consoles with the GDK](/build/console-features/networking/index.md)
- [Game mesh networking for XBOX titles](/build/console-features/networking/game-mesh/index.md)
- [XBOX 游戏的 Game mesh 网络](/zh-CN/build/console-features/networking/game-mesh/index.md)
