8. REST API를 이용해 운영툴 연동하기

게임 서비스를 하는 도중에 모니터링 툴이나 고객 지원 툴을 연동해야되는 경우가 많습니다. 이런 툴을 연동하는 방법에는 여러 방법이 있겠지만, 게임 서버가 RESTful API 를 노출하고 이 툴들이 이 API 를 호출하게 하는 것이 편리합니다. 이런 목적으로 iFun Engine 에서는 이렇게 RESTful API 를 쉽게 붙일 수 있습니다.

아이펀팩토리는 게임 서비스 운영을 손쉽게 할 수 있는 운영 툴 iFun Deploy 를 서비스 중입니다. 더 자세한 내용은 iFun Deploy 를 참고해주세요.

또한 아이펀 엔진으로 개발 된 게임 서버를 위한 모니터링 툴 역시 제공합니다. 더 자세한 내용은 아이펀 대시보드 매뉴얼 를 참고해주세요.

8.1. 운영툴 연동을 위한 REST API 추가하기

사용자 캐릭터를 블록하거나 해제하는 경우를 생각해보겠습니다. 먼저 character 에 Blocked 이라는 필드를 추가해야겠네요. hello_world-source/src/object_model/example.json 을 다음처럼 수정합니다.

{
  "User": {
    "Id": "String KEY",
    "MyCharacter": "Character"
  },
  "Character": {
    "Name": "String KEY",
    "Exp": "Integer",
    "Level": "Integer",
    "Hp": "Integer",
    "Mp": "Integer",
    "Sp": "Integer",
    "Banned": "bool"
  }
}

그리고 계정 블록을 위한 API URL 을 추가합니다. hello_world-source/src/event_handlers.cc 에 다음과 같은 내용을 추가합니다. 해당 URL 로 넘어온 character 와 state 값을 이용해서 블록 여부를 DB에 저장하는 코드입니다. 참고로 URL 은 Perl 의 정규식 형태를 사용하며, (?<user> ) 는 그 일종으로 패턴 매칭된 결과를 user 라는 이름으로 접근 가능하게 하라는 뜻입니다.

void OnBlockCharacter(
    Ptr<http::Response> response,
    const http::Request &request,
    const ApiService::MatchResult &params) {
  string character = params["character"];
  string state = params["state"];
  LOG(INFO) << "character: [" << character << "]";
  LOG(INFO) << "state: [" << state << "]";

  bool result = false;
  Ptr<Character> c = Character::FetchByName(character);
  if (c) {
    c->SetBanned(state == "1");
    result = true;
  }

  response->status_code = http::kOk;
  response->header.insert(std::make_pair("Content-Type", "plain/text"));
  response->body = result;
}


void RegisterEventHandlers() {
  ...
  ApiService::RegisterHandler(
      http::kPost,
      boost::regex("/v1/cs/ban/(?<character>\\w+)/(?<state>\\w+)"),
      OnBlockCharacter);

  ...
}

8.2. 운영툴 기능 활성화하기

API 서버의 포트 번호는 MANIFEST 에서 설정할 수 있습니다. hello_world-source/src/MANIFEST.lobby.json 에 기본값으로 8014번으로 되어있습니다.

...
"ApiService": {
  "api_service_port": 8014
},
...

주석

클라이언트 패킷 추가하기 에서 살펴본 것처럼 아이펀 엔진은 클라이언트로부터의 패킷을 HTTP 를 통해서 받을 수 있고, 이 역시 REST API 가 됩니다. 그러나 관리용 API 트래픽은 클라이언트 패킷 트래픽과 분리되는 것이 좋기 때문에 아이펀 엔진은 별도의 포트를 사용합니다.

8.3. 운영툴 기능 테스트해보기

이제 RESTful API 를 호출해봅시다. 앞서에서처럼 Chrome 이나 Firefox 플러그인을 써도 되고, 터미널에서 다음처럼 해도 됩니다. API 를 등록할 때 http::kPost 으로 POST 메소드를 쓰게 했다는 점에 주의해주세요.

로비 서버를 띄웁니다.

$ ./hello_world.lobby-local

로비 서버에 API 호출을 합니다.

$ wget --post-data="{}" -qO- http://localhost:8014/v1/cs/ban/ifun/1

서버쪽에 다음과 같은 로그 메시지가 찍히나요?

I0309 16:43:52.674099 17302 api_service.cc:81] "POST /v1/cs/ban/ifun/1" 200

어떤가요? 아주 간단하게 사용자 캐릭터를 정지하는 내용을 구현했습니다!

8.4. 기본으로 제공되는 REST API들

이 밖에도 기본적으로 제공되는 관리 API 들도 있습니다 GET /v1/ 을 호출해보시면 게임 서버에 어떤 API 들이 호출 가능한지를 확인하실 수 있습니다.

$ wget -qO- http://localhost:8014/v1/
[
    {
        "method": "GET",
        "url": "/v1/"
    },
    {
        "method": "GET",
        "url": "/v1/counters/"
    },
    {
        "method": "GET",
        "url": "/v1/counters/all/"
    },
    {
        "method": "GET",
        "url": "/v1/counters/(?<type>\\w+)/"
    },
    {
        "method": "GET",
        "url": "/v1/counters/(?<type>\\w+)/(?<id>\\w+)/"
    },
    {
        "method": "GET",
        "url": "/v1/counters/(?<type>\\w+)/(?<id>\\w+)/description/"
    },
    {
        "method": "GET",
        "url": "/v1/maintenance/"
    },
    {
        "method": "GET",
        "url": "/v1/configurations/"
    },
    {
        "method": "GET",
        "url": "/v1/configurations/(?<name>\\w+)/"
    },
    {
        "method": "POST",
        "url": "/v1/cs/ban/(?<character>\\w+)/(?<state>\\w+)/"
    },
    {
        "method": "PUT",
        "url": "/v1/maintenance/update/"
    },
    {
        "method": "PUT",
        "url": "/v1/configurations/(?<name>\\w+)/(?<value>\\w+)/"
    }
]

위의 API 들 중에서 카운터 관련된 것들은 게임 서버를 모니터링 하는데 특히 유용합니다. 호스트, OS, 엔진 의 상태값들이 카운터로 노출되며, 또한 프로그래머가 이 counter 에 값을 추가할 수도 있습니다. 예를 들어, 실제 현재 돌고 있는 서버에 대해서 (DB 에 저장되어있는거 말고, run-time 에) 생성된 비싼 아이템 갯수 등을 counter 인터페이스를 통해서 노출할 수 있습니다. 이 데이터는 DB 에 저장되는 값은 아니지만, 그 수치가 급격히 변한다면 게임 서버가 운영되는 중에 아이템 복사가 일어나는 것을 감지하는데 도움이 될 것입니다. 보다 자세한 내용은 아이펀엔진 레퍼런스 매뉴얼 을 참고해주세요.

$ wget -qO- http://localhost:8014/v1/counters
[
  "process",
  "funapi_object_model",
  "os",
  "funapi"
]
$ wget -qO- http://localhost:8014/v1/counters/funapi/sessions
0