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

게임 서비스를 하는 도중에 모니터링 툴이나 고객 지원 툴 같은 외부 툴과 연동해야 하는 경우가 많이 있습니다. 이런 툴을 연동하는 방법에는 여러 방법이 있겠지만, 게임 서버가 RESTful API 를 제공하고 이 툴들이 이 API 를 호출하게 하는 것이 편리합니다. 이런 목적으로 아이펀 엔진에서는 이렇게 RESTful API 를 쉽게 붙일 수 있는 기능도 제공합니다.

아이펀팩토리는 게임 서비스 운영과 게임 서버 모니터링을 위한 다음과 같은 툴들도 제공합니다.

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

사용자 캐릭터를 블록하거나 해제하는 경우를 생각해보겠습니다. 먼저 CharacterBanned 이라는 필드를 추가해야겠네요.

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 로 넘어온 characterstate 값을 이용해서 블록 여부를 DB 에 저장하는 코드입니다. 참고로 URLPerl 의 정규식 형태를 사용하며, (?<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 를 통해서 받을 수 있고, 이 역시 RESTful 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. 기본으로 제공되는 RESTful 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>[^/]+)/"
    },
    {
        "method": "GET",
        "url": "/v1/counters/(?<type>\\w+)/(?<id>\\w+)/description/"
    },
    {
        "method": "GET",
        "url": "/v1/configurations/"
    },
    {
        "method": "GET",
        "url": "/v1/configurations/compatible_client_versions/"
    },
    {
        "method": "GET",
        "url": "/v1/configurations/(?<name>\\w+)/"
    },
    {
        "method": "GET",
        "url": "/v1/maintenance/"
    },
    {
        "method": "POST",
        "url": "/v1/configurations/compatible_client_versions/"
    },
    {
        "method": "PUT",
        "url": "/v1/configurations/(?<name>\\w+)/(?<value>\\w+)/"
    },
    {
        "method": "PUT",
        "url": "/v1/maintenance/update/"
    }
]

위의 API 들 중에서 카운터 관련된 것들은 게임 서버를 모니터링 하는데 특히 유용합니다. 호스트, OS, 엔진 의 상태값들이 카운터로 노출되며, 또한 프로그래머가 이 카운터 종류를 추가할 수도 있습니다. 예를 들어, 실제 현재 실행중인 서버에서 생성된 희귀한 아이템의 개수를 카운터로 관리할 수 있습니다. DB 에서 데이터를 읽어올 필요없이 카운터를 모니터링해서 그 수치가 급격히 변한다면 아이템이 정상적이지 않은 방법으로 지급되는 것으로 볼 수 있을 것입니다.

보다 자세한 내용은 아이펀엔진 레퍼런스 매뉴얼 을 참고해주세요.

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