> ## 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.

# 事件管線教學課程

> 建立 PlayFab Services SDK 事件管線的逐步教學課程：初始化、遙測金鑰驗證、發出事件、附加實體，以及關閉。

本文件是關於如何在 PlayFab Services SDK 中使用事件管線功能的快速逐步教學課程。

## 步驟 1 - 初始化 PlayFab Services SDK

第一步是使用 [**PFServicesInitialize**](/zh-TW/services/playfab/api-references/c/pfservices/functions/pfservicesinitialize) 和 [**PFServiceConfigCreateHandle**](/zh-TW/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigcreatehandle) API 初始化 PF Service SDK。

**PFServiceConfigCreateHandle** API 會接收連接字串和遊戲識別碼，您可以從 PlayFab Game Manager 上的遊戲取得這些值。

第三個參數是 **PFServiceConfigHandle** 結構，代表正在建立的設定。此服務設定控制代碼將在下一個步驟中使用。

```cpp theme={null}
PFServiceConfigHandle serviceConfigHandle;

PFServicesInitialize(nullptr);

PFServiceConfigCreateHandle(
    "titleConnectionString",
    "titleId",
    &serviceConfigHandle
);
```

## 步驟 2 - 建立遙測事件管線

接下來，讓我們使用 [**PFEventPipelineCreateTelemetryPipelineHandleWithKey**](/zh-TW/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelinecreatetelemetrypipelinehandlewithkey) API，建立使用遙測金鑰的遙測事件管線。遙測金鑰是透過 PlayFab Game Manager 建立和管理的。

建立 PFEventPipelineTelemetryKeyConfig 結構時，我們會傳遞實際的遙測金鑰，以及在 SDK 初始化期間取得的服務設定控制代碼。

```cpp theme={null}
PFEventPipelineHandle handle;
XTaskQueueHandle taskQueueHandle;

XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, XTaskQueueDispatchMode::Manual, &taskQueueHandle);

PFEventPipelineTelemetryKeyConfig telemetryKeyConfig
{
    "myTelemetryKey",
    serviceConfigHandle,
};

HRESULT hr = PFEventPipelineCreateTelemetryPipelineHandleWithKey(
    &telemetryKeyConfig,
    taskQueueHandle,
    nullptr,
    nullptr,
    nullptr,
    &handle
);

if (FAILED(hr))
{
    printf("Failed creating event pipeline: 0x%x\r\n", hr);
    return;
}
```

## 步驟 3 - 更新管線設定

讓我們更新管線設定，在此範例中，我們想要以最多 10 個事件為一批傳送 (預設值為 5)。

此外，由於我們將 maxWaitTimeInSeconds 和 pollDelayInMs 傳送為 null 指標，它們會使用個別管線類型的預設值。

我們也指定了「Medium」壓縮層級，設定此屬性會壓縮本文承載，並有助於最佳化網路資源的使用率。

接著我們呼叫 [**PFEventPipelineUpdateConfiguration**](/zh-TW/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineupdateconfiguration)，並傳遞從上一個步驟取得的 **PFEventPipelineHandle** 和 **PFEventPipelineConfig** 結構。

```cpp theme={null}
uint32_t maxEvents = 10;
PFHCCompressionLevel compressionLevel = PFHCCompressionLevel::Medium;

PFEventPipelineConfig eventPipelineConfig
{
    &maxEvents,         // maxEventsPerBatch
    nullptr,            // maxWaitTimeInSeconds
    nullptr,            // pollDelayInMs
    &compressionLevel   // compressionLevel
};

HRESULT hr = PFEventPipelineUpdateConfiguration(
    handle,
    eventPipelineConfig
);

if (FAILED(hr))
{
    printf("Failed updating event pipeline configuration: 0x%x\r\n", hr);
    return;
};
```

## 步驟 4 - 發出事件

在此步驟中，我們會透過 [**PFEventPipelineEmitEvent**](/zh-TW/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineemitevent) API 發出一個名為「TelemetryKeyEvent」的事件。

由於到目前為止我們尚未提供實體驗證，因此此事件不會連結至任何實體。

```cpp theme={null}
PFEvent myEvent
{
    nullptr,
    "custom.playfab.events.PlayFab.Test.TelemetryEventPipelineTests",
    "TelemetryKeyEvent",
    nullptr,
    "{}"
};

HRESULT hr = PFEventPipelineEmitEvent(
    handle,
    &myEvent
);

if (FAILED(hr))
{
    printf("Failed emitting event: 0x%x\r\n", hr);
    return;
}
```

## 步驟 5 - 取得實體

在這裡，我們想要取得一個實體，以便開始將其與我們的事件連結。

在本教學課程中，我們會呼叫 [**PFAuthenticationReLoginWithXUserAsync**](/zh-TW/services/playfab/api-references/c/pfauthentication/functions/pfauthenticationreloginwithxuserasync) API 來取得有效的 **PFEntityHandle**。

<Note>
  作為 **PFAuthenticationLoginWithXUserRequest** 一部分傳遞的 userHandle 物件屬於 XUserHandle 類型。如何取得有效 XUserHandle 的步驟不在本教學課程的範圍內。如需此主題的詳細資訊，請參閱 [XUserAddAsync](/zh-TW/reference/system/xuser/functions/xuseraddasync) 文件。
</Note>

```cpp theme={null}
PFEntityHandle entityHandle;

PFAuthenticationLoginWithXUserRequest request{};
request.createAccount = true;
request.user = userHandle; // An XUserHandle obtained from XUserAddAsync

XAsyncBlock async{};

HRESULT hr = PFAuthenticationReLoginWithXUserAsync(entityHandle, &request, &async);

if (FAILED(hr))
{
    printf("Failed PFAuthenticationReLoginWithXUserAsync: 0x%x\r\n", hr);
    return;
}

hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage

if (FAILED(hr))
{
    printf("Failed XAsyncGetStatus: 0x%x\r\n", hr);
    return;
}
```

## 步驟 6 - 將實體新增至管線

由於我們已取得有效的實體，因此可以呼叫 [**PFEventPipelineAddUploadingEntity**](/zh-TW/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineadduploadingentity)，並傳遞事件管線控制代碼和上一個步驟中的實體控制代碼。此動作可讓管線切換為使用實體驗證。

```cpp theme={null}
HRESULT hr = PFEventPipelineAddUploadingEntity(
    handle,
    entityHandle
);

if (FAILED(hr))
{
    printf("Failed adding uploading entity: 0x%x\r\n", hr);
    return;
}
```

## 步驟 7 - 發出事件

此程序與先前的事件提交相同。

唯一的兩個差異是：

* 我們為此事件標記了不同的名稱 (「EntityEvent」)，使其更清楚。
* 此事件會被記錄並與我們先前取得的實體連結。

```cpp theme={null}
PFEvent myEvent
{
    nullptr,
    "custom.playfab.events.PlayFab.Test.TelemetryEventPipelineTests",
    "EntityEvent",
    nullptr,
    "{}"
};

hr = PFEventPipelineEmitEvent(
    handle,
    &myEvent
);

if (FAILED(hr))
{
    printf("Failed emitting event: 0x%x\r\n", hr);
    return;
}
```

## 步驟 8 - 關閉事件管線控制代碼

最後，當我們完成上傳事件時，唯一需要做的就是呼叫 [**PFEventPipelineCloseHandle**](/zh-TW/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineclosehandle)，並傳遞我們的管線控制代碼。

```cpp theme={null}
PFEventPipelineCloseHandle(handle);
```

## 另請參閱

* [事件管線概觀](/zh-TW/services/playfab/sdks/c/event-pipeline/eventpipeline)


## Related topics

- [PlayFab Services SDK - 事件管線](/zh-TW/services/playfab/sdks/c/event-pipeline/eventpipeline.md)
- [PlayFab 支援的語言](/zh-TW/services/playfab/sdks/languages/index.md)
- [PlayFab 與 Microsoft Fabric 即時分析教學課程](/zh-TW/services/playfab/data-analytics/learn-data/reports/real-time-analytics-tutorial.md)
- [教學課程：取得玩家設定檔](/zh-TW/services/playfab/player-progression/player-data/getting-player-profiles.md)
- [計算區段玩家數的教學課程](/zh-TW/services/playfab/live-service-management/game-configuration/segmentation/segmentation-player-count.md)
