본문으로 건너뛰기

세션 유지 및 중복 로그인 체크

주기적으로 서버에 세션 유지 신호를 보내고, 다른 기기에서 중복 로그인 여부를 확인하는 API입니다.

예제 코드 안내

이 문서의 예제 코드는 참고용으로 제공됩니다. Update()를 사용한 콜백 호출 방식은 매 프레임마다 체크하므로, 코루틴 내에서 직접 콜백을 호출하는 방식이 더 효율적일 수 있습니다. 실제 프로젝트에 적용하실 때는 프로젝트의 아키텍처와 코딩 컨벤션에 맞게 자유롭게 수정하여 사용하시기 바랍니다.

URL 확인

이 API는 service-account.playnanoo.com 도메인을 사용합니다.

API 정보

  • URL: https://service-account.playnanoo.com/api/v20240401/alive
  • Method: PUT
  • 인증 필요: 예

요청 파라미터

파라미터타입필수설명
platformstring필수플랫폼 (예: "aos", "ios")
device_idstring필수기기 고유 ID
device_modelstring필수기기 모델명
device_osstring필수기기 OS
device_languagestring필수기기 언어 (예: "KO", "EN")
DeviceInfo 상속

이 API의 Req 클래스는 DeviceInfo를 상속받습니다. DeviceInfo의 모든 속성이 자동으로 포함됩니다.

응답 데이터

정상 응답

필드타입설명
Statusstring상태 (정상: "success")

에러 응답

에러 코드설명
30006DuplicatedDeviceException - 다른 디바이스에서 이미 인증되었습니다

Unity C# 구현

CheckAlive 클래스

using System;
using System.Collections;
using UnityEngine.Networking;

public class CheckAlive
{
static string path = "https://service-account.playnanoo.com/api/v20240401/alive";

[Serializable]
public class Req : DeviceInfo
{
public IEnumerator Send(
Action<Res> onSuccess,
Action<BaseResponse> onError)
{
yield return HttpClient.Send<Req, Res>(
UnityWebRequest.kHttpVerbPUT,
path,
requireToken: true,
body: this,
onSuccess: onSuccess,
onError: onError
);
}
}

[Serializable]
public class Res : BaseResponse
{
public string Status;
}
}

싱글턴 매니저 클래스에 추가

싱글턴 매니저에서 주기적으로 CheckAlive를 호출하고 중복 로그인을 감지합니다.

// 변수 선언
private bool _isDuplicate = false;
private Coroutine _aliveCoroutine;
private Action<bool> _duplicateCallback;

void Update()
{
// 중복 체크 콜백이 등록되어 있고, 중복이 감지되면 콜백 호출
if (_duplicateCallback != null && _isDuplicate)
{
_duplicateCallback.Invoke(true);
_isDuplicate = false; // 한 번 호출 후 리셋
}
}

// 세션 유지 시작 (최소 300초)
public void CheckAliveStart(int delayTime = 300)
{
if (_aliveCoroutine != null) return;
int timer = delayTime < 300 ? 300 : delayTime;
_aliveCoroutine = StartCoroutine(AliveStatus(timer));
}

// 세션 유지 중지
public void CheckAliveStop()
{
if (_aliveCoroutine != null)
{
StopCoroutine(_aliveCoroutine);
_aliveCoroutine = null;
}
}

IEnumerator AliveStatus(float delayTime)
{
while (true)
{
yield return new WaitForSeconds(delayTime);

if (string.IsNullOrEmpty(DataManager.Instance.AccessToken)) continue;

CheckAlive.Req req = new CheckAlive.Req();
yield return req.Send(
onSuccess: res =>
{
// 정상 응답 - 중복 아님
},
onError: err =>
{
// 30006: DuplicatedDeviceException - 다른 디바이스에서 이미 인증됨
if (err != null && err.ErrorCode == "30006")
{
_isDuplicate = true;
}
}
);
}
}

// 중복 로그인 체크 콜백 등록
public void CheckDuplicate(Action<bool> callback)
{
_duplicateCallback = callback;
}

사용 예제

기본 사용법

void Start()
{
// 로그인 성공 후 세션 유지 시작 (300초마다)
YourSingleton.Instance.CheckAliveStart(300);

// 중복 로그인 체크 콜백 등록
YourSingleton.Instance.CheckDuplicate(OnCheckAccountDuplicate);
}

void OnCheckAccountDuplicate(bool isDuplicate)
{
if (isDuplicate)
{
Debug.LogError("Duplicate connection has been detected.");
// 강제 로그아웃 처리
// 예: 로그인 화면으로 이동, 토큰 삭제 등
}
}

로그아웃 시 세션 유지 중지

public void Logout()
{
// 세션 유지 중지
YourSingleton.Instance.CheckAliveStop();

// 기타 로그아웃 처리...
}

동작 흐름

  1. 로그인 성공CheckAliveStart(300) 호출
  2. 300초마다 서버에 alive 요청 전송
  3. 정상 응답: 세션 유지됨
  4. 에러 30006: 다른 기기에서 로그인됨 → _isDuplicate = true
  5. Update(): 중복 감지 시 등록된 콜백 호출
  6. 콜백 처리: 강제 로그아웃, 알림 표시 등

주의사항

중복 호출 금지

CheckAliveStart()앱 전체에서 단 한 번만 호출해야 합니다.

  • 여러 씬이나 컴포넌트에서 중복으로 호출하면 안 됩니다.
  • 중복 호출 시 서버에서 비정상적인 요청 패턴으로 감지되어 오탐(false positive)으로 중복 로그인 에러(30006)가 발생할 수 있습니다.
  • 싱글턴 패턴을 사용하여 한 곳에서만 세션 유지를 관리하세요.
  • 이미 타이머가 실행 중인 경우 내부적으로 중복 호출을 방지하지만, 구조적으로 단일 호출 지점을 유지하는 것이 좋습니다.