GS2-Gateway SDK for Game Engine API 레퍼런스

게임 엔진용 GS2-Gateway SDK의 모델 사양과 API 레퍼런스

모델

EzWebSocketSession

WebSocketSession

WebSocket 세션은 GS2 서버와 클라이언트 간의 지속적인 연결로, 실시간 양방향 통신을 수행합니다.
서버에 대해 클라이언트 측에서 식별자로 사용자 ID를 등록합니다.

타입활성화 조건필수기본값값 제한설명
connectionIdstring
~ 128자커넥션 ID
이 WebSocket 접속에 할당된 고유 식별자입니다. 알림 송신 시 특정 클라이언트 접속을 식별하는 데 사용됩니다.
namespaceNamestring
~ 128자네임스페이스 이름
userIdstring
~ 128자사용자ID

EzFirebaseToken

Firebase 디바이스 토큰

Firebase 디바이스 토큰은 모바일 푸시 알림을 이용할 때 필요합니다.

GS2-Gateway는 게임 내 푸시 알림 기능을 제공하여 매치메이킹 완료 시나 미션 달성 시 푸시 알림을 받을 수 있지만
알림 대상 플레이어가 오프라인인 경우 모바일 푸시 알림으로 전달할 수 있습니다.

이때 알림 대상 디바이스를 특정하여 알림을 보내는 데 사용되는 것이 Firebase 디바이스 토큰입니다.
이름 그대로 Firebase라는 외부 서비스를 이용하므로, 토큰 취득 방법 등 자세한 내용은 Firebase 문서를 확인해 주세요.

타입활성화 조건필수기본값값 제한설명
userIdstring
~ 128자사용자ID
tokenstring
~ 1024자Firebase Cloud Messaging의 디바이스 토큰
클라이언트 디바이스에서 취득한 FCM 등록 토큰입니다. 플레이어가 오프라인이어서 게임 내 WebSocket 알림을 수신할 수 없는 경우, 모바일 푸시 알림을 전달할 특정 디바이스를 식별합니다. 토큰은 디바이스 고유의 값이며 앱을 재설치하거나 데이터를 삭제하면 변경될 수 있습니다.
localestring~ 32자알림 메시지의 로케일
이 디바이스에 전달할 알림 메시지의 로케일입니다. ja / en과 같은 자유 형식의 문자열이며, 정해진 값의 목록으로 제한되지 않습니다. 알림이 모바일 푸시 알림으로 전달될 때, 페이로드가 {locale, message} 요소를 가진 mobile 배열을 포함하는 JSON인 경우, 이 로케일과 일치하는 요소가 푸시 알림의 본문으로 사용됩니다. 일치하는 요소가 없는 경우에는 default 로케일을 가진 요소가, 그것도 없는 경우에는 배열의 첫 번째 요소가 사용됩니다. 페이로드가 해당 형식이 아닌 경우에는 페이로드가 그대로 사용됩니다. 이 항목은 선택 사항이며, 설정되지 않은 경우에는 default 요소·첫 번째 요소·페이로드 자체만 적용됩니다.

메서드

setUserId

서버로부터의 푸시 알림을 수신하기 위해 플레이어의 접속을 등록한다

현재 WebSocket 접속을 플레이어의 사용자 ID에 연결하여, 서버가 이 클라이언트에 실시간 푸시 알림을 전송할 수 있도록 합니다.
일반적으로 플레이어가 로그인하여 서버에 접속한 직후에 호출합니다. 이 단계를 거치지 않으면 서버는 어느 접속이 어느 플레이어의 것인지 판별할 수 없습니다.
allowConcurrentAccess 플래그로 동일한 플레이어가 여러 디바이스에서 동시에 접속할 수 있는지를 제어합니다:

  • true: 여러 동시 접속을 허용(스마트폰과 태블릿 양쪽에서 플레이하는 경우 등)
  • false: 플레이어당 1개의 접속만 허용(중복 로그인 방지. 기존 접속은 연결 해제됩니다)
    게임의 로그인·초기화 흐름의 일부로 사용합니다. 실시간 채팅 알림, 친구 요청 알림, 매치메이킹 성사 알림 등의 기능을 활성화하는 데 필요합니다.

Request

타입활성화 조건필수기본값값 제한설명
namespaceNamestring
~ 128자네임스페이스 이름
gameSessionGameSession
GameSession
allowConcurrentAccessbooltrue동시에 다른 클라이언트로부터의 접속을 허용할지 여부
sessionIdstring{allowConcurrentAccess} == false~ 128자allowConcurrentAccess를 false로 설정한 경우에도, 기존 접속과 동일한 sessionId라면 접속을 허용하기 위해 지정합니다.

Result

타입설명
itemEzWebSocketSession갱신한 WebSocket 세션

구현 예제

    var domain = gs2.Gateway.Namespace(
        namespaceName: "$hash"
    ).Me(
        gameSession: GameSession
    ).WebSocketSession(
    );
    var result = await domain.SetUserIdAsync(
        allowConcurrentAccess: true,
        sessionId: null
    );
    var item = await result.ModelAsync();
    var domain = gs2.Gateway.Namespace(
        namespaceName: "$hash"
    ).Me(
        gameSession: GameSession
    ).WebSocketSession(
    );
    var future = domain.SetUserIdFuture(
        allowConcurrentAccess: true,
        sessionId: null
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    const auto Domain = Gs2->Gateway->Namespace(
        "$hash" // namespaceName
    )->Me(
        GameSession
    )->WebSocketSession(
    );
    const auto Future = Domain->SetUserId(
        true // allowConcurrentAccess
        // sessionId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();
var domain = ez.gateway.namespace_(
        "$hash"
    ).me(game_session).web_socket_session(
    )

var async_result = await domain.set_user_id(
    true, # allow_concurrent_access
    null # session_id
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

deleteFirebaseToken

이 단말기로의 모바일 푸시 알림 전달을 중지한다

플레이어에게 등록되어 있는 FCM 디바이스 토큰을 삭제합니다.
삭제하면 오프라인 시에 도착한 알림이 모바일 푸시 알림으로 전달되지 않게 되며, 게임 내의 WebSocket 알림만 남습니다.
플레이어가 로그아웃할 때(공용 단말기에서 다음 플레이어에게 이전 플레이어 앞으로 온 알림이 도착하지 않도록 하기 위해)나, 게임의 설정 화면에서 플레이어가 알림을 끈 경우에 호출해 주세요.
토큰을 삭제해도 계정의 다른 정보에는 영향이 없습니다. 다시 토큰을 등록하면 모바일 푸시 알림의 수신을 재개할 수 있습니다.

Request

타입활성화 조건필수기본값값 제한설명
namespaceNamestring
~ 128자네임스페이스 이름
네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.
gameSessionGameSession
GameSession

Result

타입설명
itemEzFirebaseToken삭제한 Firebase 디바이스 토큰

구현 예제

    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var result = await domain.DeleteFirebaseTokenAsync(
    );
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var future = domain.DeleteFirebaseTokenFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    const auto Domain = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->FirebaseToken(
    );
    const auto Future = Domain->DeleteFirebaseToken(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();
var domain = ez.gateway.namespace_(
        "namespace-0001"
    ).me(game_session).firebase_token(
    )

var async_result = await domain.delete_firebase_token(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

getFirebaseToken

플레이어에게 등록되어 있는 디바이스 토큰을 가져온다

플레이어에게 현재 등록되어 있는 FCM 디바이스 토큰을 가져옵니다.
이 단말기에서 이미 토큰을 등록했는지 확인하는 데 사용합니다. 예를 들어 알림 권한을 요청하고 토큰을 등록할 필요가 있는지 판단하거나, “알림 설정” 화면에서 현재 상태를 표시하는 데 이용할 수 있습니다.
토큰이 등록되어 있지 않은 경우에는 요청이 not found 에러가 되므로, 그 경우는 “아직 알림 설정이 되어 있지 않다"로 처리해 주세요.
등록되어 있는 토큰은 플레이어가 이전에 사용하던 다른 단말기의 것일 가능성도 있으므로, 이 단말기에서 Firebase SDK로부터 취득한 토큰과 비교한 뒤에 등록을 생략할지 판단해 주세요.

Request

타입활성화 조건필수기본값값 제한설명
namespaceNamestring
~ 128자네임스페이스 이름
네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.
gameSessionGameSession
GameSession

Result

타입설명
itemEzFirebaseTokenFirebase 디바이스 토큰

구현 예제

    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var item = await domain.ModelAsync();
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;
    const auto Domain = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->FirebaseToken(
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
var domain = ez.gateway.namespace_(
        "namespace-0001"
    ).me(game_session).firebase_token(
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result
값 변경 이벤트 핸들링
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);
    const auto Domain = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->FirebaseToken(
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Gateway::Model::FFirebaseToken> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);
var domain = ez.gateway.namespace_(
        "namespace-0001"
    ).me(game_session).firebase_token(
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

setFirebaseToken

모바일 푸시 알림의 전달 대상이 되는 디바이스 토큰을 등록한다

플레이어의 단말기에서 Firebase SDK로부터 취득한 FCM 디바이스 토큰을 등록(갱신)합니다.
서버로부터의 푸시 알림은 일반적으로 플레이어의 WebSocket 접속을 통해 전달되지만, 플레이어가 오프라인이어서 WebSocket 세션이 없는 경우에는 여기에서 등록한 토큰을 사용하여 모바일 푸시 알림으로 전달됩니다.
이를 통해 게임을 닫아 둔 플레이어에게도 “매치메이킹이 성사되었다”, “스태미나가 모두 회복되었다”, “친구 신청이 도착했다"와 같은 알림을 보낼 수 있습니다.
로그인 직후 Firebase SDK로부터 토큰을 받은 시점에 호출하고, 나아가 Firebase가 토큰 갱신을 통지할 때마다 호출해 주세요. 토큰은 단말기 고유의 값이며 앱 재설치나 데이터 삭제, Firebase 측의 로테이션에 의해 변경됩니다.
이미 토큰이 등록되어 있는 경우에는 덮어쓰기만 되므로, 게임을 시작할 때마다 호출해도 문제없습니다.
locale에는 플레이어의 언어 설정(예를 들어 jaen)을 전달해 주세요. 알림의 페이로드에 여러 언어의 메시지가 포함되어 있는 경우, 해당 로케일과 일치하는 메시지가 모바일 푸시 알림에 사용됩니다.

Request

타입활성화 조건필수기본값값 제한설명
namespaceNamestring
~ 128자네임스페이스 이름
네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다.
gameSessionGameSession
GameSession
tokenstring
~ 1024자Firebase Cloud Messaging의 디바이스 토큰
클라이언트 디바이스에서 취득한 FCM 등록 토큰입니다. 플레이어가 오프라인이어서 게임 내 WebSocket 알림을 수신할 수 없는 경우, 모바일 푸시 알림을 전달할 특정 디바이스를 식별합니다. 토큰은 디바이스 고유의 값이며 앱을 재설치하거나 데이터를 삭제하면 변경될 수 있습니다.
localestring~ 32자알림 메시지의 로케일
이 디바이스에 전달할 알림 메시지의 로케일입니다. ja / en과 같은 자유 형식의 문자열이며, 정해진 값의 목록으로 제한되지 않습니다. 알림이 모바일 푸시 알림으로 전달될 때, 페이로드가 {locale, message} 요소를 가진 mobile 배열을 포함하는 JSON인 경우, 이 로케일과 일치하는 요소가 푸시 알림의 본문으로 사용됩니다. 일치하는 요소가 없는 경우에는 default 로케일을 가진 요소가, 그것도 없는 경우에는 배열의 첫 번째 요소가 사용됩니다. 페이로드가 해당 형식이 아닌 경우에는 페이로드가 그대로 사용됩니다. 이 항목은 선택 사항이며, 설정되지 않은 경우에는 default 요소·첫 번째 요소·페이로드 자체만 적용됩니다.

Result

타입설명
itemEzFirebaseToken생성한 Firebase 디바이스 토큰

구현 예제

    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var result = await domain.SetFirebaseTokenAsync(
        token: "firebase-token-0001",
        locale: null
    );
    var item = await result.ModelAsync();
    var domain = gs2.Gateway.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).FirebaseToken(
    );
    var future = domain.SetFirebaseTokenFuture(
        token: "firebase-token-0001",
        locale: null
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    const auto Domain = Gs2->Gateway->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->FirebaseToken(
    );
    const auto Future = Domain->SetFirebaseToken(
        "firebase-token-0001" // token
        // locale
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();
var domain = ez.gateway.namespace_(
        "namespace-0001"
    ).me(game_session).firebase_token(
    )

var async_result = await domain.set_firebase_token(
    "firebase-token-0001", # token
    null # locale
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result