イベント パイプライン

イベント パイプラインは PlayFab Services SDK の一部である機能であり、主な目的は、ゲーム開発者が PlayFab Insights に格納されるイベントを送信できるようにすることです。 これにより、開発者はバッチ サイズ、送信頻度、適切なテレメトリ ソリューションのその他の側面を指定できます。

これは、ゲーム開発者の負担を軽減し、それらのすべての側面を彼らの代わりに処理するのに役立ちます。 構成可能なイベント パイプラインのサポートがあります。 タイトルには、これらのパイプラインを 1 つ以上含めることができます。また、それぞれに独自のプロパティを使用して構成できます。

パイプラインの基本的な概念をいくつか見てみましょう。

パイプラインの種類

パイプラインの種類は、パイプラインによって出力されるイベントの種類に直接関連します。 開発者がインスタンス化できるパイプラインには、次の 2 種類があります。

異なる種類と構成を持つ複数のパイプラインを使用できますが、作成後にパイプラインの種類を変更することはできません。パイプラインの再インスタンス化が必要です。

認証の種類

パイプライン作成のもう 1 つの重要な部分は、認証の種類です。 PlayFab イベントには、エンティティ認証とテレメトリ キー認証という 2 つの認証メカニズムがサポートされています。

エンティティ認証は、ゲーム開発者が特定のエンティティに対してイベントをリンクして、さらに集計または分析する場合に使用されます。 たとえば、ゲーム開発者は、プレイヤーのアクションに関連するイベントをログに記録して、セグメント化を可能にするタイトル プレイヤーの動作分析をさらに行うことができます。

テレメトリ キー認証は、ゲーム開発者が必ずしもエンティティにリンクする必要のないイベントをログに記録する場合に使用されます。 たとえば、プレイヤーがログインする前に、タイトルはパフォーマンスに関連するイベントの送信を開始したり、さらに分析するために収集する特定のメトリックを開始したりできます。 これは、通常のエンティティ認証プロセスを経ることなく実行できます。

サポートされている認証の種類/イベントの種類の組み合わせ

エンティティ認証 テレメトリ キー認証
テレメトリ イベント 有効 有効
PlayStream イベント 有効 無効

エンティティ認証

この認証の種類は、通常の最も一般的な PlayFab 認証方法です。 特定のエンティティと密接に関連しており、後続の呼び出しで使用するエンティティ トークンを取得するには、対応する PlayFab ログイン API を呼び出す必要があります。 次の一覧は、エンティティ認証で使用できるさまざまな種類のエンティティを表しています。

  • 名前空間: 名前空間エンティティは、スタジオ内のすべてのタイトルのすべてのグローバル情報を参照します。
  • タイトル: タイトル エンティティは、タイトルのすべてのグローバル情報を参照します。
  • master_player_account: master_player_account は、スタジオ内の全タイトル間で共有されるプレイヤー エンティティです。
  • title_player_account: ほとんどの開発者にとって、title_player_account は最も従来的な意味でプレイヤーを表します。
  • 文字: 文字エンティティは、title_player_account のサブエンティティです。
  • グループ: グループ エンティティは、他のエンティティのコンテナーです。 現在、プレイヤーとキャラクターに制限されています。

さまざまなエンティティ型の詳細については、「 組み込みのエンティティ型」を参照してください。

また、パイプライン エンティティは、有効な PFEntityHandle を指定することで、パイプラインの作成後に更新できます。 そのため、ゲーム開発者はエンティティを追加してイベントへのリンクを開始したり (エンティティ認証への切り替え」または「エンティティの更新」セクションを参照)、エンティティに関連していないものをログに記録する必要があるエンティティを削除することもできます (テレメトリ キー認証への切り替え」セクションを参照)。

パイプラインにエンティティが存在する場合は、テレメトリ キー認証よりも常に優先されます。

テレメトリ キー認証

テレメトリ キー認証ではエンティティ トークンは必要ないため、特定のエンティティに関連付けられません。

テレメトリ キー認証を使用する場合は、パイプラインの作成時に PFEventPipelineTelemetryKeyConfig 構造体が必要です。 この構造体には、次の 2 つのメイン部分があります。

  1. PlayFab ゲーム マネージャーを使用して作成および管理される文字列で構成されるテレメトリ キー。

  2. イベントのアップロードに使用する適切なサービス構成が SDK に認識されるようにする PFServiceConfigHandle。 サービス構成ハンドルは、PFServiceConfigCreateHandle を呼び出すことによって、SDK の初期化中に作成されます。

開発者がテレメトリ キーを使用する場合は、パイプラインのインスタンス化後にテレメトリ キーを追加する方法がないため、パイプラインの作成時に提供することが重要です。

テレメトリ キー認証はテレメトリ イベントでのみ使用できること、PlayStream イベントはサポートされていないことに注意してください。

イベント パイプラインの構成

前述のように、イベント パイプラインには、PFEventPipelineConfig 構造体パラメーターを使用してパイプラインを作成した後に提供できる構成可能なプロパティがいくつかあります。

構成可能なプロパティは次のとおりです。

  • maxEventsPerBatch: PlayFab に書き込む前にバッチ処理されるイベントの最大数。
  • maxWaitTimeInSeconds: 不完全なバッチを送信する前にパイプラインが待機する最大時間。
  • pollDelayInMs: パイプラインがイベント バッファーを空にした後にイベント バッファーからの読み取りを待機する時間。
  • compressionLevel: 圧縮アルゴリズムで使用される圧縮レベルを定義します。 圧縮の詳細については、「GZIP 圧縮」を参照してください。
  • retryOnDisconnect: 接続が失われたために失敗したイベントの送信を、イベント パイプラインが再試行します。 テレメトリ イベント パイプラインでのみ使用できます。
  • bufferSize: パイプラインのバッファーに格納できるイベントの量の制限。

PFEventPipelineConfig に一部のプロパティのみが指定されている場合、空のプロパティは上書きされ、既定値が使用されます。

イベント パイプラインでこれらのプロパティを更新する方法の例については、「パイプライン構成の更新」を参照してください。

GZIP 圧縮

イベント パイプラインには、GZIP 圧縮標準を使用して本文ペイロードを圧縮するオプションが用意されています。

必要な圧縮レベルは、PFEventPipelineUpdateConfiguration API パラメーターの一部である PFEventPipelineConfig 構造体内で指定できます。

圧縮レベルが低いと圧縮率は低くなりますが、圧縮速度は最も高くなります。圧縮レベルが高いと圧縮率は向上しますが、圧縮速度は最も遅くなります。 圧縮率の違いはすべて、送信されるデータの種類によって異なります。 データのサイズとランダム性に応じて、圧縮率は異なるレベルでも同じにすることができます。

トレードオフ:

圧縮を使用すると、圧縮アルゴリズムの実行が複雑になり、CPU 時間が長くなりますが、一方で、ネットワーク本文のペイロードは大幅に減少します。 そのため、ゲームのニーズとリソースに応じて、圧縮を使用する必要がある場合はゲーム開発者が行います。

内部検証に基づいて、CPU 時間が平均 20% 増加し、ペイロード本文サイズが平均 91% 減少します。 これらの割合は、圧縮されるデータのペイロード サイズと複雑さによって大きく異なる場合があります。

イベント ハンドラー

パイプラインの作成の一環として、ゲーム開発者は、イベントのアップロード時に呼び出される 2 つのオプションのイベント ハンドラーを提供できます。

ただし、ゲーム開発者が "fire and forget" エクスペリエンスを必要とする場合は、イベント ハンドラーの提供を省略できます。

指定できるイベント ハンドラーは次のとおりです。

  • PFEventPipelineBatchUploadSucceededEventHandler: 名前が示すように、PlayFab に正常にアップロードされたすべてのイベントを受信します。

  • PFEventPipelineBatchUploadFailedEventHandler: パイプラインの再試行ロジックを実行すると、失敗したすべてのイベントが受信されます。

パイプラインの作成例

前に説明したトピックに基づいてイベント パイプラインをインスタンス化する方法のさまざまな例を次に示します。

  1. エンティティ認証を使用したテレメトリ イベント パイプラインの作成

    開発者がテレメトリ イベントを送信する必要があり、テレメトリ キー認証を使用する必要がない場合は、次の例に示すように 、PFEventPipelineCreateTelemetryPipelineHandleWithEntity API がこの目的で機能します。

    void EventPipelineCreation(PFEntityHandle entityHandle, XTaskQueueHandle taskQueueHandle)
    {
        PFEventPipelineHandle handle;
    
        HRESULT hr = PFEventPipelineCreateTelemetryPipelineHandleWithEntity(
            entityHandle,                       // entityHandle
            taskQueueHandle,                    // queue
            nullptr,                            // eventPipelineBatchUploadedEventHandler
            nullptr,                            // eventPipelineBatchFailedEventHandler
            nullptr,                            // handlerContext
            &handle                             // eventPipelineHandle
        );
    
        if (FAILED(hr))
        {
            printf("Failed creating event pipeline: 0x%x\r\n", hr);
            return;
        }
    }
    

    この例では、エンティティ認証を使用し、ハンドラーを持たないテレメトリ イベント パイプラインを作成する方法を示します。 これは、パイプラインがイベントを発生させ、結果を忘れることを意味します。

  2. テレメトリ キー認証を使用したテレメトリ イベント パイプラインの作成

    開発者がテレメトリ イベントを送信する必要があり、テレメトリ キー認証を使用する必要がある場合、PFEventPipelineCreateTelemetryPipelineHandleWithKey API は、次の例に示すようにこの目的を果たします。

    void EventPipelineCreation(PFServiceConfigHandle serviceConfigHandle, XTaskQueueHandle taskQueueHandle)
    {
        PFEventPipelineHandle handle;
    
        PFEventPipelineTelemetryKeyConfig telemetryKeyConfig
        {
            "myTelemetryKey",                   // telemetryKey
            serviceConfigHandle,                // serviceConfigHandle
        };
    
        HRESULT hr = PFEventPipelineCreateTelemetryPipelineHandleWithKey(
            &telemetryKeyConfig,                // eventPipelineTelemetryKeyConfig
            taskQueueHandle,                    // queue
            nullptr,                            // eventPipelineBatchUploadedEventHandler
            nullptr,                            // eventPipelineBatchFailedEventHandler
            nullptr,                            // handlerContext
            &handle                             // eventPipelineHandle
        );
    
        if (FAILED(hr))
        {
            printf("Failed creating event pipeline: 0x%x\r\n", hr);
            return;
        }
    }
    

    この例では、エンティティ認証を使用していないテレメトリ イベント パイプラインを作成する方法を示します。

    イベント パイプラインは、後でエンティティを追加する可能性があるテレメトリ キーを使用してイベントのアップロードを開始します。 「エンティティ認証または更新エンティティへの切り替え」を参照してください

  3. PlayStream イベント パイプラインの作成

    開発者が PlayStream イベントを送信する場合、PFEventPipelineCreatePlayStreamPipelineHandle API は、次の例のようにこの目的を果たします。

    void EventPipelineCreation(PFEntityHandle entityHandle, XTaskQueueHandle taskQueueHandle)
    {
        PFEventPipelineHandle handle;
    
        HRESULT hr = PFEventPipelineCreatePlayStreamPipelineHandle(
            entityHandle,                       // entityHandle
            taskQueueHandle,                    // queue
            nullptr,                            // eventPipelineBatchUploadedEventHandler
            nullptr,                            // eventPipelineBatchFailedEventHandler
            nullptr,                            // handlerContext
            &handle                             // eventPipelineHandle
        );
    
        if (FAILED(hr))
        {
            printf("Failed creating event pipeline: 0x%x\r\n", hr);
            return;
        }
    }
    

    この例では、エンティティ認証を使用する PlayStream イベント パイプラインを作成し、ハンドラーを持たない方法を示します。 これは、パイプラインがイベントを発生させ、結果を忘れることを意味します。

  4. イベント ハンドラーを使用したイベント パイプライン

    この例では、パイプライン作成 API にイベント ハンドラーを提供する方法を示します。

    void CALLBACK OnBatchUploadedHandler(void* context, PFUploadedEvent const* const* events, size_t eventsCount)
    {
        // Handle response
    }
    
    void CALLBACK OnBatchUploadFailedHandler(void* context, HRESULT hr, const char* errorMessage, PFEvent const* const* events, size_t eventsCount)
    {
        // Handle response
    }
    
    void EventPipelineCreation(PFEntityHandle entityHandle, XTaskQueueHandle taskQueueHandle)
    {
        PFEventPipelineHandle handle;
    
        HRESULT hr = PFEventPipelineCreateTelemetryPipelineHandleWithEntity(
            entityHandle,                       // entityHandle
            taskQueueHandle,                    // queue
            OnBatchUploadedHandler,             // eventPipelineBatchUploadedEventHandler
            OnBatchUploadFailedHandler,         // eventPipelineBatchFailedEventHandler
            nullptr,                            // handlerContext
            &handle                             // eventPipelineHandle
        );
    
        if (FAILED(hr))
        {
            printf("Failed creating event pipeline: 0x%x\r\n", hr);
            return;
        }
    }
    

この例に示すように、 OnBatchUploadedHandlerOnBatchUploadFailedHandler は、イベント パイプラインの作成時に渡される 2 つの異なるコールバック関数として宣言されています。 イベントに関連付けられているすべての結果は、結果が成功したか失敗したかに応じて、これら 2 つの関数のいずれかで返されます。 結果を処理する方法は、ゲーム開発者が行います。

イベントの出力

イベント パイプラインが既に作成されている場合、イベントの出力は簡単な操作です。 ゲーム開発者は、既存のイベント パイプライン ハンドルと送信するイベントを受け取る PFEventPipelineEmitEvent API を呼び出す必要があります。

void EmitEvent(PFEventPipelineHandle handle)
{
    PFEvent myEvent
    {
        nullptr,
        "custom.playfab.events.PlayFab.Test.TelemetryEventPipelineTests",
        "TelemetryEvent",
        nullptr,
        "{}"
    };

    HRESULT hr = PFEventPipelineEmitEvent(
        handle,
        &myEvent
    );

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

テレメトリ キー認証を使用する場合、 PFEntityKey の一部としての entityType の唯一の有効な値は "外部" であることに注意してください。 その他のエンティティ型は拒否され、イベントはアップロードされません。

テレメトリ キー認証を使用する場合の有効な PFEntityKey の例:

void EmitEvent(PFEventPipelineHandle handle)
{
    PFEntityKey pfEntityKey{ "my-unique-ID", "external" };  // Note the "external" value

    PFEvent myEvent
    {
        &pfEntityKey,
        "custom.playfab.events.PlayFab.Test.EventsWithTelemetryKey",
        "TelemetryEvent",
        nullptr,
        "{}"
    };

    HRESULT hr = PFEventPipelineEmitEvent(
        handle,
        &myEvent
    );

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

イベントが生成されたとき、バッファー サイズの制限を超えている場合は、以下のように SDK のエラーが発生します。

  • E_PF_API_CLIENT_REQUEST_RATE_LIMIT_EXCEEDED (0x892354dd)

必要に応じた適切なバッファー サイズを設定してください。

エンティティ認証への切り替えまたはエンティティの更新

テレメトリ キー構成のみを使用してパイプラインが作成された場合は、エンティティ認証に切り替える方法や、別のエンティティを使用するようにパイプラインを更新する方法があります。

PFEventPipelineAddUploadingEntity を使用すると、エンティティを再初期化することなく、実行中のパイプラインにアタッチできます。 既存のエンティティ (存在する場合) も置き換えられます。

以下に例を示します。

テレメトリ イベント パイプラインは、タイトルの実行の開始時にテレメトリ キー構成で作成されます。 その理由として、プレイヤー ID がまだ存在しないか、単にプレイヤーに関連するものをまだログに記録したくないことが考えられます。

void EventPipelineCreation(PFServiceConfigHandle serviceConfigHandle, XTaskQueueHandle taskQueueHandle)
{
    PFEventPipelineHandle handle;

    PFEventPipelineTelemetryKeyConfig telemetryKeyConfig
    {
        "myTelemetryKey",                   // telemetryKey
        serviceConfigHandle,                // serviceConfigHandle
    };

    HRESULT hr = PFEventPipelineCreateTelemetryPipelineHandleWithKey(
        &telemetryKeyConfig,                // eventPipelineTelemetryKeyConfig
        taskQueueHandle,                    // queue
        nullptr,                            // eventPipelineBatchUploadedEventHandler
        nullptr,                            // eventPipelineBatchFailedEventHandler
        nullptr,                            // handlerContext
        &handle                             // eventPipelineHandle
    );

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

次に、プレイヤーがログインしたか、特定のエンティティにアタッチされたイベントの送信を開始するだけで、次のように既存のイベント パイプライン ハンドルと目的のエンティティ ハンドルを使用して PFEventPipelineAddUploadingEntity を呼び出すことができます。

void EventPipelineUpdateEntity(PFEventPipelineHandle handle)
{
    HRESULT hr = PFEventPipelineAddUploadingEntity(
        handle,                 // eventPipelineHandle
        entityHandle            // entityHandle
    );

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

この呼び出しの後、パイプラインはそのエンティティにリンクされた後続のイベントのログ記録を開始します。

テレメトリ キー認証への切り替え

前のシナリオを拡張すると、開発者がテレメトリ認証に戻り、エンティティからイベント ログをデタッチする場合は、 PFEventPipelineRemoveUploadingEntity を呼び出して、次のようなイベント パイプライン ハンドルを渡すことができます。

void EventPipelineRemoveEntity(PFEventPipelineHandle handle)
{
    HRESULT hr = PFEventPipelineRemoveUploadingEntity(
        handle                  // eventPipelineHandle
    );

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

この呼び出しによってエンティティが削除され、後続のすべてのイベントのテレメトリ キー認証に効果的に切り替わります。

パイプライン構成の更新

パイプラインは、次のように既存のイベント パイプライン ハンドルと新しい構成構造体を受け取る PFEventPipelineUpdateConfiguration API を使用して簡単に更新できます。

void EventPipelineUpdateConfiguration(PFEventPipelineHandle handle)
{
    uint32_t maxEvents = 10;
    uint32_t maxWaitTime = 5;
    uint32_t pollDelay = 50;
    PFHCCompressionLevel compressionLevel = PFHCCompressionLevel::Medium;
    bool retryOnDisconnect = true;
    size_t bufferSize = 2048;

    PFEventPipelineConfig eventPipelineConfig
    {
        &maxEvents,             // maxEventsPerBatch
        &maxWaitTime,           // maxWaitTimeInSeconds
        &pollDelay,             // pollDelayInMs
        &compressionLevel,      // compressionLevel
        &retryOnDisconnect,     // retryOnDisconnect
        &bufferSize,            // bufferSize
    };

    HRESULT hr = PFEventPipelineUpdateConfiguration(
        handle,                 // eventPipelineHandle
        eventPipelineConfig     // eventPipelineConfig
    );

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

リマインダー: 空または null のプロパティは、既存の構成値を既定値で上書きします。

無効/非アクティブ化されたテレメトリ キー

テレメトリ キーが非アクティブ化された場合、またはパイプラインの作成時に無効なキーが指定されている場合、そのテレメトリ キーを使用して実行されているイベント パイプラインは、キーが無効または非アクティブであることが判明するとすぐに失敗し始めます。

最終的に顧客がキーを再アクティブ化する場合、パイプラインはそのことを認識せず、失敗したイベント ハンドラーを介してエラーを送信し続けます。 この動作はセッション ベースであるため、タイトルが再起動されると、新しいパイプラインが作成され、イベントを再度アップロードできることを意味します。

関連項目