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

# XSAPI C를 통한 사용자 Presence 업데이트

> XblPresenceSetPresenceAsync를 사용하여 XBOX services 사용자의 온라인 Presence 상태를 업데이트하고 현재 게임 내 활동을 알리는 Flat C 샘플입니다.

이 항목에서는 사용자의 온라인 Presence 상태를 설정하기 위한 예제 코드를 제공합니다. XBOX services Rich Presence는 다른 플레이어에게 플레이어의 현재 활동을 알리는 기능을 제공합니다.

자세한 내용은 [Rich Presence 개요](https://docs.xbox.com/ko/services/xbox-services/community/presence/live-presence-overview.md)를 참조하세요.

## 사용자의 온라인 Presence 상태 업데이트

이 예제 코드는 사용자의 온라인 Presence 상태를 설정합니다.

다음 예제에서는 Flat C API를 사용합니다.

```cpp theme={null}
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->queue = queue;
asyncBlock->context = nullptr;
asyncBlock->callback = [](XAsyncBlock* asyncBlock)
{
    std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of XAsyncBlock*.
    HRESULT hr = XAsyncGetStatus(asyncBlock, false);
    if (FAILED(hr))
    {
        // Log the failure. To choose how to handle it, call XblGetErrorCondition(hr).
    }
};

HRESULT hr = XblPresenceSetPresenceAsync(xboxLiveContext, true, nullptr, asyncBlock.get());
if (SUCCEEDED(hr))
{
    // The call succeeded, so release the std::unique_ptr ownership of XAsyncBlock* because the callback will take over ownership.
    // If the call fails, std::unique_ptr will keep ownership and delete XAsyncBlock*.
    asyncBlock.release();
}
```

자세한 내용은 다음을 참조하세요.

* [XAsyncBlock](https://docs.xbox.com/ko/reference/system/xasync/structs/xasyncblock.md)
* [XAsyncGetStatus](https://docs.xbox.com/ko/reference/system/xasync/functions/xasyncgetstatus.md)
* [XblPresenceSetPresenceAsync](https://docs.xbox.com/ko/reference/live/xsapi-c/presence_c/functions/xblpresencesetpresenceasync.md)

## Rich Presence 상태 업데이트

다음 예제에서는 사용자에 대해 `playingMap` Rich Presence 문자열을 설정합니다. 이 예제에서 `playingMap`은 토큰이 없는 정적 문자열로 구성되어 있습니다. `xboxLiveContext`는 사용자의 `XblContextHandle`이고, `queue`는 게임의 작업 큐이거나 프로세스 기본 작업 큐를 사용하려면 `nullptr`입니다.

```cpp theme={null}
#include <memory>
#include <string.h>
#include <xsapi-c/services_c.h>

HRESULT SetRichPresence(XblContextHandle xboxLiveContext, XTaskQueueHandle queue)
{
    // Get the SCID that you passed to XblInitialize.
    const char* scid = nullptr;
    HRESULT hr = XblGetScid(&scid);
    if (FAILED(hr))
    {
        return hr;
    }

    XblPresenceRichPresenceIds ids{};
    if (strcpy_s(ids.scid, sizeof(ids.scid), scid) != 0)
    {
        return E_INVALIDARG;
    }
    ids.presenceId = "playingMap";

    // Use a new XAsyncBlock for each call.
    auto asyncBlock = std::make_unique<XAsyncBlock>();
    asyncBlock->queue = queue;
    asyncBlock->context = nullptr;
    asyncBlock->callback = [](XAsyncBlock* asyncBlock)
    {
        std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock }; // Take over ownership of XAsyncBlock*.
        HRESULT result = XAsyncGetStatus(asyncBlock, false);
        if (FAILED(result))
        {
            // Log every failure. To choose how to handle it, call XblGetErrorCondition(result).
            // For XblErrorCondition::Http429TooManyRequests, don't retry right away.
        }
    };

    hr = XblPresenceSetPresenceAsync(xboxLiveContext, true, &ids, asyncBlock.get());
    if (SUCCEEDED(hr))
    {
        // The callback now owns the XAsyncBlock.
        asyncBlock.release();
    }
    return hr;
}
```

구성된 Presence 문자열에 명시적인 대체 문자열이 필요한 경우 `presenceTokenIds`를 자리 표시자 순서대로 구성된 문자열 ID로 설정하고, `presenceTokenIdsCount`를 배열 길이로 설정하세요.

`scid` 또는 `presenceId` 멤버가 비어 있으면 요청에는 활성 또는 비활성 상태만 포함되고 Rich Presence 문자열은 포함되지 않습니다.

자세한 내용은 다음을 참조하세요.

* [XblGetErrorCondition](https://docs.xbox.com/ko/reference/live/xsapi-c/errors_c/functions/xblgeterrorcondition.md)
* [XblGetScid](https://docs.xbox.com/ko/reference/live/xsapi-c/xbox_live_global_c/functions/xblgetscid.md)
* [XblPresenceRichPresenceIds](https://docs.xbox.com/ko/reference/live/xsapi-c/presence_c/structs/xblpresencerichpresenceids.md)
* [XblPresenceSetPresenceAsync](https://docs.xbox.com/ko/reference/live/xsapi-c/presence_c/functions/xblpresencesetpresenceasync.md)

## 속도 제한 및 인증

Presence 서비스는 각 사용자 및 타이틀에 대해 15초에 3회 쓰기와 300초에 30회 쓰기를 허용합니다. 플레이어의 활동이 변경될 때 Rich Presence를 업데이트하고, 빠르게 연속되는 변경 내용은 하나의 업데이트로 결합하세요. Rich Presence를 주기적으로 새로 고치기도 하는 경우 합산된 속도를 두 제한 내로 유지하세요.

호출이 `HTTP_E_STATUS_429_TOO_MANY_REQUESTS`(`XblErrorCondition::Http429TooManyRequests`)로 실패하면 루프에서 다시 시도하지 마세요. 서비스 응답에는 Retry-After 헤더가 포함되며 XSAPI는 이를 준수합니다.

인증 테스트 [XR-132](https://docs.xbox.com/ko/publishing/certification/xr/xr-132.md)는 요청 속도가 지속 제한의 10배(300초에 Presence 쓰기 300회) 이상인 타이틀을 불합격 처리합니다. 이 임계값은 안전한 운영 허용치가 아닙니다. 자세한 내용은 [세분화된 속도 제한](https://docs.xbox.com/ko/services/xbox-services/develop/best-practices/live-fine-grained-rate-limiting.md)을 참조하세요.


## Related topics

- [Rich Presence 예제 코드(목차)](https://docs.xbox.com/ko/services/xbox-services/community/presence/how-to/live-presence-howto-nav.md)
- [Rich Presence 개요](https://docs.xbox.com/ko/services/xbox-services/community/presence/live-presence-overview.md)
- [Rich Presence 모범 사례](https://docs.xbox.com/ko/services/xbox-services/community/presence/concepts/live-presence-best-practices.md)
- [REST를 통한 사용자 Presence 업데이트](https://docs.xbox.com/ko/services/xbox-services/community/presence/how-to/live-updating-presence-rest.md)
- [제품 변경 및 콘텐츠 업데이트](https://docs.xbox.com/ko/publishing/game-publishing/publishing-processes/managed-creators/publishing-processes-post-release-lifecycle.md)
