동기/비동기/SendQueue

뒤끝은 총 3가지의 함수 방식을 지원합니다.

  • 동기
  • 비동기
  • SendQueue

각각의 함수방식에는 장단점이 있으며, 어느 하나만 골라서 사용하는 것이 아닌 모든 것을 적절히 섞어서 사용하는 것을 추천합니다.

동기 방식

요청 시점에서 시간이 얼마나 걸리던지 요청한 자리에서 결과가 주어지는 함수입니다.
함수를 호출하면 리턴값이 반환될때까지 메인 쓰레드의 동작이 중지하게 되어 게임이 멈춘 것처럼 보일 수 있습니다.

비동기함수와는 다르게 순차적으로 함수가 호출되어 순서가 섞일 가능성이 없으며, 작업 도중 다른 쓰레드에 의해 오류가 발생할 경우가 없기 때문에 확실한 결과를 제공합니다.

사용되는 상황

확실하게 이루어져야하는 기능을 호출 시 사용이 추천됩니다.

  • 로그인, 토큰 갱신등의 로그인 기능
  • 영수증 검증, 결재 아이템 받기등의 과금 관련 기능

Example

//유저 정보 불러오기(동기)
Backend.BMember.GetUserInfo();
// 이후의 행동

비동기 방식

동기함수와는 다르게 호출 시점에서 실행결과를 기다리지 않는 함수입니다.

비동기 함수의 경우 비동기 함수를 호출한 쓰레드에서 해당 함수 호출에 대한 결과를 기다리지 않고 바로 다음 작업을 수행할 수 있습니다.
이 때 로딩같은 작업을 수행하면 사용자에게 프로그램이 멈춘 것이 아닌 데이터를 로딩 혹은 저장 중이라는 경험을 제공할 수 있습니다.

비동기 함수의 콜백함수는 비동기 IO 쓰레드 내에서 실행되게 됩니다.
이 때 유니티의 정책에 따라 별도의 쓰레드에서는 유니티 MonoBehaviour 객체에 접근할 수 없습니다.
즉 콜백 함수 내에서는 유니티 객체, UI 객체 등에 접근할 수 없기 때문에 비동기 함수의 요청 결과에 따른 처리를 위해서는
별도의 Dispatcher의 사용이 필요할 수 있습니다.

여러 개의 비동기 함수를 거의 동시에(for루프 등) 호출하는 경우 아래 조건에서 요청시간이 비정상적으로 길어질 수 있습니다.

  • 서버로 보내는 요청이 OS 스케줄러에 따라 대기하고 있다가, 대기하고 있던 요청들이 한번에 서버로 전송되는 경우 요청시간이 비정상적으로 길어질 수 있습니다.
  • 현재 클라이언트에서 사용중인 비동기 IO 쓰레드의 갯수보다 많은 수의 비동기 요청을 한번에 호출할 경우 새로 IO 쓰레드를 생성하는 과정에서 요청시간이 비정상적으로 길어질 수 있습니다.

사용되는 상황

SDK 5.2.1 미만 버전에서는 비동기 함수를 한번에 4개 이상 호출 시 요청시간이 비정상적으로 길어질 수 있습니다.
SDK 5.2.1 미만을 사용하는 개발사에서는 SDK 5.2.1 이상 버전으로 업데이트를 권장합니다.

대부분의 상황에서 함수 호출 시 사용이 추천됩니다.

  • 현재 시점에 요청 8개 이하 호출하는 것이 권장
  • 함수가 순차적으로 호출 될 필요가 없을 때
  • 게임 종료시점에 현재 데이터를 종료할 때

Example

//유저 정보 불러오기(비동기)
Backend.BMember.GetUserInfo( callback =>
{
// 이후의 행동
});

SendQueue 방식

비동기 함수 호출 시 바로 호출하지 않고 큐에 적재한 후 순차적으로 함수를 호출하는 방식입니다.
동기의 장점인 순차적으로 호출되는 점과 비동기의 장점인 함수 호출의 결과를 기다리지 않고 바로 다음 작업이 수행되며 프로그램이 중지되지 않는 것처럼 보인다는 점이 합쳐져 있습니다.

SendQueue에 들어간 함수들은 함수가 호출되고 응답이 받은 이후에 다음 함수가 호출됩니다.
이로 인해 함수는 순차적으로 호출되지만 많은 요청을 SendQueue에 삽입한 경우 순서에 따라 진행되기 때문에 함수의 호출이 밀리는 상황이 발생할 수 있습니다.

SendQueue에 적재된 함수의 콜백함수는 유니티의 메인쓰레드에서 동작하도록 설계되었습니다.
그렇기에 비동기 함수와 다르게 콜백함수 내에서 유니티 객체 및 UI 객체에 접근할 수 있습니다.

사용되는 상황

대부분의 상황에서 함수 호출 시 사용이 추천됩니다.

  • 순차적으로 호출 될 필요가 있을 때

Example

//유저 정보 불러오기(SendQueue)
SendQueue.Enqueue(Backend.BMember.GetUserInfo, callback =>
{
 // 이후의 행동
});