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

# Tutorial do Event Pipeline

> Tutorial passo a passo para criar um pipeline de eventos do SDK do PlayFab Services: inicializar, autenticar com chave de telemetria, emitir eventos, anexar uma entidade e fechar.

Este documento é um tutorial rápido e passo a passo sobre como usar o recurso Event Pipeline no SDK do PlayFab Services.

## Etapa 1 - Inicializar o SDK do PlayFab Services

A primeira etapa é inicializar o SDK do PF Service usando as APIs [**PFServicesInitialize**](/pt-BR/services/playfab/api-references/c/pfservices/functions/pfservicesinitialize) e [**PFServiceConfigCreateHandle**](/pt-BR/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigcreatehandle).

A API **PFServiceConfigCreateHandle** recebe uma cadeia de conexão e uma ID de título, que podem ser obtidas do seu título no PlayFab Game Manager.

O terceiro parâmetro é um struct **PFServiceConfigHandle** que representa a configuração que está sendo criada. Esse identificador de configuração de serviço será usado na próxima etapa.

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

PFServicesInitialize(nullptr);

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

## Etapa 2 - Criar o pipeline de eventos de telemetria

Em seguida, vamos criar um pipeline de eventos de telemetria com uma chave de telemetria usando a API [**PFEventPipelineCreateTelemetryPipelineHandleWithKey**](/pt-BR/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelinecreatetelemetrypipelinehandlewithkey). As chaves de telemetria são criadas e gerenciadas pelo PlayFab Game Manager.

Ao criar o struct PFEventPipelineTelemetryKeyConfig, passamos a chave de telemetria real e o identificador de configuração de serviço obtido durante a inicialização do 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;
}
```

## Etapa 3 - Atualizar a configuração do pipeline

Vamos atualizar a configuração do pipeline. Neste exemplo, queremos enviar lotes de no máximo 10 eventos (o padrão é 5).

Além disso, como estamos enviando maxWaitTimeInSeconds e pollDelayInMs como ponteiros nulos, eles usam o valor padrão do respectivo tipo de pipeline.

Também estamos especificando um nível de compactação "Medium". Definir essa propriedade compacta os payloads do corpo e ajuda a otimizar o uso dos recursos de rede.

Em seguida, chamamos [**PFEventPipelineUpdateConfiguration**](/pt-BR/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineupdateconfiguration), passando o **PFEventPipelineHandle** obtido na etapa anterior e o struct **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;
};
```

## Etapa 4 - Emitir um evento

Nesta etapa, emitimos apenas 1 evento com o nome "TelemetryKeyEvent" por meio da API [**PFEventPipelineEmitEvent**](/pt-BR/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineemitevent).

Este evento não está vinculado a nenhuma entidade, pois até agora não fornecemos autenticação de entidade.

```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;
}
```

## Etapa 5 - Obter uma entidade

Aqui, queremos obter uma entidade que possamos começar a vincular aos nossos eventos.

Neste tutorial, estamos chamando a API [**PFAuthenticationReLoginWithXUserAsync**](/pt-BR/services/playfab/api-references/c/pfauthentication/functions/pfauthenticationreloginwithxuserasync) para obter um **PFEntityHandle** válido.

<Note>
  O objeto userHandle passado como parte de **PFAuthenticationLoginWithXUserRequest** é do tipo XUserHandle. As etapas para obter um XUserHandle válido estão fora do escopo deste tutorial. Para obter mais informações sobre esse assunto, consulte a documentação de [XUserAddAsync](/pt-BR/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;
}
```

## Etapa 6 - Adicionar a entidade ao pipeline

Como já obtivemos uma entidade válida, podemos chamar [**PFEventPipelineAddUploadingEntity**](/pt-BR/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineadduploadingentity) e passar o identificador do pipeline de eventos e o identificador de entidade da etapa anterior. Essa ação permite que o pipeline passe a usar a autenticação de entidade.

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

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

## Etapa 7 - Emitir um evento

Este procedimento é igual ao do envio de evento anterior.

As únicas duas diferenças são:

* Estamos marcando este evento com um nome diferente ("EntityEvent") para deixar mais claro.
* Este evento é registrado e vinculado à entidade que obtivemos anteriormente.

```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;
}
```

## Etapa 8 - Fechar o identificador do pipeline de eventos

Por fim, quando terminarmos de carregar os eventos, a única coisa que precisamos fazer é chamar [**PFEventPipelineCloseHandle**](/pt-BR/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineclosehandle), passando nosso identificador de pipeline.

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

## Confira também

* [Visão geral do Event Pipeline](/pt-BR/services/playfab/sdks/c/event-pipeline/eventpipeline)


## Related topics

- [SDK do PlayFab Services - Event Pipeline](/pt-BR/services/playfab/sdks/c/event-pipeline/eventpipeline.md)
- [PFEventPipelineEmitEvent](/pt-BR/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineemitevent.md)
- [PFEventPipelineUpdateConfiguration](/pt-BR/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineupdateconfiguration.md)
- [PFEventPipelineConfig](/pt-BR/services/playfab/api-references/c/pfeventpipeline/structs/pfeventpipelineconfig.md)
- [PFEventPipelineRemoveUploadingEntity](/pt-BR/services/playfab/api-references/c/pfeventpipeline/functions/pfeventpipelineremoveuploadingentity.md)
