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

# 使用直接對等連線

> 在 PlayFab Party 中啟用直接對等連線，直接在端點之間路由流量，而不經過透明的雲端轉送，以降低延遲。

# PlayFab Party 與直接對等連線

本頁使用範例遊戲程式碼，說明如何在 PlayFab Party 中啟用及使用直接對等連線。其中也包含相關考量，協助您評估何時在遊戲中使用直接對等連線。

## 何時使用直接對等連線

PlayFab Party 支援各種通訊拓撲。概念上，所有聊天或資料訊息都是從一個對等裝置或使用者直接傳送給其他人。不過，Party 會自動運用透明的雲端轉送服務，以避免建立直接對等連線時常見的環境和安全性問題。您可以運用其背景服務品質 (QoS) 測量來實現低延遲的資料傳輸。(如需詳細資訊，請參閱 [PlayFab Party QoS 測量](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/concepts-regions.md)。) 您可以選擇啟用直接對等連線，以進一步降低資料傳輸延遲。基於下方「安全性考量」中詳述的安全性疑慮，除非您的遊戲有嚴格的延遲需求，否則 Microsoft 建議您使用我們的雲端轉送服務，而不是啟用直接對等連線。

### 平台支援

Windows 10、Microsoft Game Core、Nintendo Switch、PlayStation®4 和 PlayStation®5 版本的 Party 程式庫支援直接對等連線。其他版本的程式庫一律會使用雲端轉送進行資料傳輸，而不論透過用戶端 API 指定的直接對等連線選項為何。

「PlayStation」是 Sony Interactive Entertainment Inc. 的註冊商標或商標。

### 安全性考量

由於直接對等連線用於在用戶端之間直接傳送資料，因此所有用戶端都需要知道如何彼此連線。這是透過在同一個遊戲工作階段中的用戶端之間分享用戶端 IP 位址來完成。例如，如果 16 人的多人遊戲使用直接對等連線來更新玩家位置，16 個遊戲用戶端中的每一個都需要知道其他 15 個用戶端的 IP 位址，才能知道要將資料傳送給誰。

在遊戲用戶端之間分享 IP 位址具有安全性風險。分享 IP 位址可能會讓不肖人士偵測到 IP 位址，並在遊戲之外利用它惡意攻擊其他玩家。執行這些攻擊的常見方法是阻斷服務 (DOS) 攻擊，或其變體分散式阻斷服務 (DDOS) 攻擊。這些攻擊的運作方式是嘗試以多餘的網路流量淹沒網路。如果攻擊者能將足夠的網路流量傳送給受害者，受害者的網路硬體 (數據機和路由器) 就必須花費所有時間處理多餘的流量，而沒有任何時間執行處理合法網路連線的正常工作。實際上，這表示受害者在攻擊持續期間都無法使用其網路。這通常稱為「被踢下線」。

總而言之，成功的直接對等連線可能會在某些裝置之間提供較低的延遲。不過，嘗試建立直接對等連線也需要使用者向其他人揭露其 IP 位址，這可能讓惡意使用者在遊戲之外攻擊其裝置和網際網路連線。基於原則考量，某些平台也可能不允許直接對等連線。請務必針對您的效能和安全性目標使用適當的直接對等連線選項。如果您在權衡風險後決定使用直接對等連線，請使用下列範例，以每個網路和每個裝置為單位讓您的遊戲選擇加入。

### LAN 案例

Party 中的直接對等連線可用於在 LAN 案例中實現極低的延遲。不過，即使在這些案例中，仍需要有限的網際網路連線，以支援使用者驗證、LiveOps 資料和深入解析，以及語音聊天協助工具功能。

### 上游頻寬考量

使用直接對等連線可能會增加遊戲的上游頻寬使用量。透過雲端轉送服務傳輸遊戲或語音訊息時，Party 會將單一訊息傳送至服務，接著服務會複寫該訊息並轉送至每個目標裝置。透過直接對等連線傳輸遊戲或語音訊息時，Party 會為每個已建立直接對等連線的目標裝置複寫訊息，並透過直接連線傳送。因此，遊戲的上游頻寬使用量會與已建立直接對等連線的裝置數目成正比。在啟用直接對等連線之前，請考慮上游頻寬的這種增加對您的遊戲而言是否可以接受。

## 如何在遊戲中使用直接對等連線

### 在網路中啟用直接對等連線

透過 [`PartyManager::CreateNewNetwork()`](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/classes/PartyManager/methods/partymanager_createnewnetwork) 建立網路時，您可以透過提供給呼叫的 [`PartyNetworkConfiguration`](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/structs/partynetworkconfiguration) 指定各種網路設定參數。您可以使用 `PartyNetworkConfiguration::directPeerConnectivityOptions` 欄位，指定網路中的裝置是否支援直接對等連線，以及支援的方式。

下列範例顯示的網路設定，指定應在網路中的所有裝置之間嘗試直接對等連線，而不論平台類型或登入提供者為何。

```cpp theme={null}
PartyNetworkConfiguration configuration = {};
configuration.directPeerConnectivityOptions = PartyDirectPeerConnectivityOptions::AnyPlatformType | PartyDirectPeerConnectivityOptions::AnyEntityLoginProvider;
// Initialize the rest of the network configuration parameters appropriately for your game before using.
```

在將初始使用者成功驗證到網路的過程中，若網路設定允許，裝置可能會嘗試與已參與網路的其他裝置建立直接對等連線。對於成功的嘗試，裝置之間的端點訊息和聊天資料會使用這些直接連線傳輸。對於因裝置之間環境不相容而失敗的嘗試，這些裝置之間的所有通訊都會改為透過透明的雲端轉送伺服器傳輸。如果網路設定不允許裝置嘗試直接對等連線，則它們永遠不會交換 IP 位址資訊，且一律會透過透明的雲端轉送伺服器傳輸端點訊息和聊天資料。

> [!NOTE]
>
> 建立直接對等連線是盡力而為的，可能會因為環境因素、個別裝置的連線選項或平台原則而無法建立。如需評估是否已與特定裝置建立直接對等連線的詳細資訊，請參閱[評估連線類型和延遲](#evaluating-the-connection-type-and-latency)。

### 依裝置限制直接對等連線

除了網路設定中的直接對等連線選項之外，裝置還可以使用 [`PartyManager::SetOption()`](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/classes/PartyManager/methods/partymanager_setoption) 設定 [`PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask`](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partyoption)，針對其驗證進入的所有網路進一步限制直接對等連線。所有旗標都會使用位元 AND 運算進行評估。也就是說，只有當特定旗標在三個地方都已啟用時 (網路設定，以及兩個裝置各自的本機遮罩選項)，該旗標才會對指定網路中的一對裝置生效。即使網路設定允許相關形式的直接對等連線，任一裝置都可以藉由不在其本機裝置遮罩選項中啟用該旗標，獨立選擇退出彼此之間的 IP 位址揭露和直接連線嘗試。在支援直接對等連線的程式庫版本中，`PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask` 值預設為允許網路啟用的所有直接對等連線。因此，只有在您有裝置專屬需求，要防止涉及本機裝置的部分或全部直接對等連線時，才需要設定它。

下列範例顯示如何限制本機裝置的直接對等連線，使其只會嘗試與相同平台的裝置建立直接對等連線。

```cpp theme={null}
PartyDirectPeerConnectivityOptions localDeviceMask = PartyDirectPeerConnectivityOptions::SamePlatformType | PartyDirectPeerConnectivityOptions::AnyEntityLoginProvider;
PartyError error = PartyManager::GetSingleton().SetOption(nullptr, PartyOption::LocalDeviceDirectPeerConnectivityOptionsMask, &localDeviceMask);
if (PARTY_FAILED(error))
{
    printf("Failed to set local device direct peer connectivity options mask! error = 0x%08x\n", error);
}
```

### 評估連線類型和延遲

您可以呼叫 [`PartyNetwork::GetDeviceConnectionType()`](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/classes/PartyNetwork/methods/partynetwork_getdeviceconnectiontype)，判斷本機裝置是否已與特定遠端裝置建立直接對等連線。

建議您不要主動強制任何一對裝置都必須有直接對等連線 (也就是說，如果 PartyNetwork::GetDeviceConnectionType() 回報的值不是 [`PartyDeviceConnectionType::DirectPeerConnection`](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partydeviceconnectiontype)，請勿呼叫 [`PartyNetwork::LeaveNetwork()`](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/classes/PartyNetwork/methods/partynetwork_leavenetwork))，因為使用中的特定基礎傳輸方法並不會改變整體的邏輯通訊能力。如果您的遊戲設計對訊息延遲上限有嚴格的需求而傾向使用直接對等連線，最好根據 [`PartyEndpointStatistic::AverageDeviceRoundTripLatencyInMilliseconds`](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partyendpointstatistic) 統計資料所回報的目前實際延遲觀察值採取動作，而不是根據傳輸機制做出抽象的假設。否則，您可能會持續妨礙那些因無法控制的環境因素而總是需要使用附近透明雲端轉送伺服器、卻想與同一群好友遊玩的使用者。

下列範例顯示如何檢查 `network` 中從 `localEndpoint` 到 `remoteEndpoint` 的來回延遲。

```cpp theme={null}
// A helper for inspecting the connection type and average round trip latency between a local endpoint and a remote
// endpoint in a network.
void PrintConnectionTypeAndLatency(
    PartyNetwork* network,
    PartyLocalEndpoint* localEndpoint,
    PartyEndpoint* remoteEndpoint
    )
{
    // Retrieve the device associated with the remote endpoint.
    PartyDevice* remoteDevice;
    PartyError error = remoteEndpoint->GetDevice(&remoteDevice);
    if (PARTY_FAILED(error))
    {
        printf("Failed to get the remote device! error = 0x%08x\n", error);
        return;
    }

    // Get the device connection type.
    PartyDeviceConnectionType connectionType;
    PartyError error = network->GetDeviceConnectionType(remoteDevice, &connectionType);
    if (PARTY_FAILED(error))
    {
        printf("Failed to get device connection type! error = 0x%08x\n", error);
        return;
    }

    // Retrieve the latency statistic.
    PartyEndpointStatistic latencyStatistic = PartyEndpointStatistic::AverageDeviceRoundTripLatencyInMilliseconds;
    uint64_t latencyStatisticValue;
    error = localEndpoint->GetEndpointStatistics(
        1,                       // targetEndpointCount
        &remoteEndpoint,         // targetEndpoints
        1,                       // statisticCount
        &latencyStatistic,       // statisticTypes
        &latencyStatisticValue); // statisticValues
    if (PARTY_FAILED(error))
    {
        printf("Failed to get latency statistic! error = 0x%08x\n", error);
        return;
    }

    // Print the results.
    printf("Local endpoint 0x%p and remote endpoint 0x%p in network 0x%p have average round trip latency %llu ms and device connection type %i\n",
        localEndpoint,
        remoteEndpoint,
        network,
        latencyStatisticValue,
        static_cast<int32_t>(connectionType));
}
```

### 連線類型的變更

環境條件的變化可能會中斷直接對等連線，使其無法供 PlayFab Party 使用。
如果發生這種情況，裝置會嘗試回復為透過雲端轉送伺服器進行通訊。如果仍可進行轉送通訊，[PartyNetwork::GetDeviceConnectionType()](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/classes/PartyNetwork/methods/partynetwork_getdeviceconnectiontype.md) 函式就會開始回報 [PartyDeviceConnectionType::RelayServer](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partydeviceconnectiontype.md)，且裝置之後會使用新的連線類型繼續留在 Party 網路中。否則，連線中斷的裝置將會離開網路。

> [!WARNING]
>
> 直接對等連線中斷時，仍在該連線上傳輸或接收過程中的聊天和遊戲訊息可能永遠不會送達，即使這些訊息是使用 [PartySendMessageOptions::GuaranteedDelivery](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partysendmessageoptions.md) 傳送，且即使它們已不再計入 [PartyLocalEndpoint::GetEndpointStatistics()](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/classes/PartyLocalEndpoint/methods/partylocalendpoint_getendpointstatistics.md) 所傳回的 [PartyEndpointStatistic::CurrentlyQueuedSendMessages](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partyendpointstatistic.md) 或 [PartyEndpointStatistic::CurrentlyActiveSendMessages](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partyendpointstatistic.md) 值中。

此外，在連線類型轉換期間傳輸的訊息可能會不依順序送達，即使是使用 [PartySendMessageOptions::SequentialDelivery](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partysendmessageoptions.md) 傳送也一樣。
使用直接對等連線和這些 PartySendMessageOptions 時，您的遊戲應為資料遺失和順序錯亂的可能性做好準備。

PartyDeviceConnectionType::RelayServer 連線類型永遠不會變更為其他類型，無論該值是在裝置最初加入網路時指派，還是在先前中斷的直接對等連線之後指派。

## 計費計量

使用直接對等連線的網路，與使用雲端轉送服務的網路，會套用相同的[計費計量](https://docs.xbox.com/zh-TW/services/playfab/pricing/meters/meters.md#party)。不過，只有經過雲端轉送服務的遊戲或語音資料，才會計入 **Network egress** 和 **Party voice** 計量。


## Related topics

- [PlayFab Party 版本資訊](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/release-notes.md)
- [PartyDirectPeerConnectivityOptions](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partydirectpeerconnectivityoptions.md)
- [DirectPeerConnectivityOptions](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/unity-party-api-reference/enums/partyunitydirectpeerconnectivityoptions.md)
- [PartyDeviceConnectionType](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/reference/enums/partydeviceconnectiontype.md)
- [PlayFab Party 連接埠使用方式與防火牆需求](https://docs.xbox.com/zh-TW/services/playfab/multiplayer/networking/concepts-port-usage.md)
