Http Client 기능

아이펀 엔진의 HTTP Client 기능

만일 아이펀 엔진의 인증 검증이나 결제 검증에서 다루지 않는 플랫폼을 지원해야되거나, 그 외에 다른 목적으로 외부 시스템을 REST 방식으로 연동해야되는 경우를 위해 아이펀 엔진은 RESTful API 를 호출할 수 있는 HttpClientHttpClientPool 을 제공합니다. API 호출이 빈번하다면 HttpClientPool 사용을 권장하며, 아래에서 설명합니다.

Tip

보다 자세한 내용은 API 문서 를 참고해주세요.

Note

아이펀 엔진의 HTTP client 는 libcurl 에 기반하고 있기 때문에, HTTP client 의 에러코드는 libcurl 의 오류 코드 를 참고해주세요.

HTTP Client

Note

HttpClient 은 C++ 버전만 제공되며, C#에서는 HttpWebRequest 클래스를 통해 HTTP 통신을 구현할 수 있습니다.

헤더 설정

HttpClient 은 각 요청 별로 헤더를 추가, 삭제, 리셋할 수 있는 메소드를 제공합니다. 사용 방법은 아래와 같습니다.

void SetHeader(const string &key, const string &value);
void UnsetHeader(const string &key);
void ResetHeader();

...
void Example() {
  Ptr<HttpClient> http_client(new HttpClient);
  // 헤더 값을 추가합니다.
  http_client->SetHeader("Content-Type", "application/json");
  http_client->SetHeader("...", "...");

  // 헤더 값을 제거합니다.
  http_client->UnsetHeader("...");

  // 헤더 값을 초기화합니다.
  http_client->ResetHeader();
  ...
}

C# 에서는 HttpWebRequest 클래스를 사용합니다.

public static void Example()
{
    string strUri = "http://www.example.com";
    System.Net.HttpWebRequest request =
        (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
    request.Headers.Add("Content-Type", "application/json");
    request.Headers.Add("...", "...");
    ...
}

예제: GET 메소드

동기 방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
void Example() {
  Ptr<HttpClient> http_client(new HttpClient);

  if (http_client->Get("http://example.com") != CURLE_OK) {
    LOG(ERROR) << "http request failure: "
               << http_client->error_message();
    return;
  }

  const http::Response &response = http_client->response();

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

C# 에서는 HttpWebRequest 클래스를 사용합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public static void Example()
{
    string strUri = "http://www.example.com";
    System.Net.HttpWebRequest request =
        (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
    request.Method = "GET";

    System.Net.HttpWebResponse response =
        (System.Net.HttpWebResponse)request.GetResponse();

    if (response.StatusCode != HttpStatusCode.OK) {
        Log.Error("http request failure");
        return;
    }

    System.IO.Stream respStream = response.GetResponseStream();
    System.IO.StreamReader streamReader =
        new System.IO.StreamReader(
            respStream, System.Text.Encoding.Default);
    string strResult = streamReader.ReadToEnd();

    Log.Info ("Response: {0}", strResult);

    // 만약 Json 기반의 RESTful API라면 아래를 참고합니다.
    //  JToken token = JToken.Parse (strResult);
    //  if (token is JObject) {
    //    JObject jsonResponse = token.ToObject<JObject>();
    //    Log.Info ("Response: {0}", jsonResponse.ToString());
    //  } else if (token is JArray) {
    //    JArray jsonResponse = token.ToJArray ();
    //    foreach(JObject obj in jsonResponse)
    //    {
    //      Log.Info ("Response: {0}", obj.ToString());
    //    }
    //  }
}
비동기 방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void OnResponseReceived1(const CURLcode code, const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void OnResponseReceived2(const CURLcode code, const string &error_message,
                        const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure: " << error_message;
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void Example() {
  Ptr<HttpClient> http_client(new HttpClient);

  // GetAsync() 함수로 간단하게 HTTP GET 요청을 할 수 있습니다.
  http_client->GetAsync("http://example.com", OnResponseReceived1);

  // GetAsync2() 함수는 콜백 인자에 오류 메시지 문자열도 포함됩니다.
  http_client->GetAsync2("http://example.com", OnResponseReceived2);
}

C#에서는 HttpWebRequest 클래스와 AsyncCallback 클래스를 통해 비동기 방식의 HTTP API 통신을 구현할 수 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public static void OnResponseReceived(IAsyncResult result)
{
    System.Net.HttpWebResponse response =
        (result.AsyncState as HttpWebRequest).EndGetResponse (result)
            as HttpWebResponse;

    if (response.StatusCode != HttpStatusCode.OK) {
        Log.Error("http request failure");
        return;
    }

    System.IO.Stream respStream = response.GetResponseStream();
    System.IO.StreamReader streamReader =
        new System.IO.StreamReader(
            respStream, System.Text.Encoding.Default);
    string strResult = streamReader.ReadToEnd();

    Log.Info ("Response: {0}", strResult);

    // 만약 Json 기반의 RESTful API라면 아래를 참고합니다.
    //  JToken token = JToken.Parse (strResult);
    //  if (token is JObject) {
    //    JObject jsonResponse = token.ToObject<JObject>();
    //    Log.Info ("Response: {0}", jsonResponse.ToString());
    //  } else if (token is JArray) {
    //    JArray jsonResponse = token.ToJArray ();
    //    foreach(JObject obj in jsonResponse)
    //    {
    //      Log.Info ("Response: {0}", obj.ToString());
    //    }
    //  }
}

public static void Example()
{
    string strUri = "http://www.example.com";
    System.Net.HttpWebRequest request =
        (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
    request.Method = "GET";

    request.BeginGetResponse(new AsyncCallback(OnResponseReceived), request);
}

예제: POST 메소드

동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void Example() {
  Ptr<HttpClient> http_client(new HttpClient);

  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP POST 요청을 보냅니다.
  // Post 함수는 post data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string, curl_httppost
  if (http_client->Post("http://example.com", data) != CURLE_OK) {
    LOG(ERROR) << "http request failure: "
               << http_client->error_message();
    return;
  }

  const http::Response &response = http_client->response();

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

C# 에서는 HttpWebRequest 클래스를 사용합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static void Example()
{
    string strUri = "http://example.com";
    System.Net.HttpWebRequest request =
      (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
    request.Method = "POST";

    JObject data = new JObject ();
    data ["example"] = "hello world!";
    byte[] contentBytes =
        System.Text.UTF8Encoding.UTF8.GetBytes(data.ToString());

    request.ContentLength = contentBytes.Length;
    System.IO.Stream requestStream = request.GetRequestStream();
    requestStream.Write(contentBytes, 0, contentBytes.Length);
    requestStream.Close();

    System.Net.HttpWebResponse response =
      (System.Net.HttpWebResponse)request.GetResponse();

    if (response.StatusCode != HttpStatusCode.OK) {
      Log.Warning("http request failure");
      return;
    }

    System.IO.Stream respStream = response.GetResponseStream();
    System.IO.StreamReader streamReader =
      new System.IO.StreamReader(respStream, System.Text.Encoding.Default);
    string strResult = streamReader.ReadToEnd ();

    Log.Info ("Response: {0}", strResult);

    // 만약 Json 기반의 RESTful API라면 아래를 참고합니다.
    //  JToken token = JToken.Parse (strResult);
    //  if (token is JObject) {
    //    JObject jsonResponse = token.ToObject<JObject>();
    //    Log.Info ("Response: {0}", jsonResponse.ToString());
    //  } else if (token is JArray) {
    //    JArray jsonResponse = token.ToJArray ();
    //    foreach(JObject obj in jsonResponse)
    //    {
    //      Log.Info ("Response: {0}", obj.ToString());
    //    }
    //  }
}
비동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void OnResponseReceived(const CURLcode code, const string &error_message,
                        const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure: " << error_message;
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void Example() {
  Ptr<HttpClient> http_client(new HttpClient);

  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP POST 요청을 보냅니다.
  // PostAsync 함수는 post data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string, curl_httppost
  http_client->PostAsync2("http://example.com", data, OnResponseReceived);
}

C#에서는 HttpWebRequest 클래스와 AsyncCallback 클래스를 통해 비동기 방식의 HTTP API 통신을 구현할 수 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  public static void OnResponseReceived(IAsyncResult result)
  {
      System.Net.HttpWebResponse response =
          (result.AsyncState as HttpWebRequest).EndGetResponse (result)
              as HttpWebResponse;

      if (response.StatusCode != HttpStatusCode.OK) {
          Log.Error("http request failure");
          return;
      }

      System.IO.Stream respStream = response.GetResponseStream();
      System.IO.StreamReader streamReader =
          new System.IO.StreamReader(
              respStream, System.Text.Encoding.Default);
      string strResult = streamReader.ReadToEnd();

      Log.Info ("Response: {0}", strResult);

      // 만약 Json 기반의 RESTful API라면 아래를 참고합니다.
      //  JToken token = JToken.Parse (strResult);
      //  if (token is JObject) {
      //    JObject jsonResponse = token.ToObject<JObject>();
      //    Log.Info ("Response: {0}", jsonResponse.ToString());
      //  } else if (token is JArray) {
      //    JArray jsonResponse = token.ToJArray ();
      //    foreach(JObject obj in jsonResponse)
      //    {
      //      Log.Info ("Response: {0}", obj.ToString());
      //    }
      //  }
  }

  public static void Example()
  {
      string strUri = "http://example.com";
      System.Net.HttpWebRequest request =
        (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
      request.Method = "POST";

      JObject data = new JObject ();
      data ["example"] = "hello world!";
      byte[] contentBytes =
          System.Text.UTF8Encoding.UTF8.GetBytes(data.ToString());

      request.ContentLength = contentBytes.Length;
      System.IO.Stream requestStream = request.GetRequestStream();
      requestStream.Write(contentBytes, 0, contentBytes.Length);
      requestStream.Close();

      request.BeginGetResponse(new AsyncCallback(OnResponseReceived), request);
  }

예제: PUT 메소드

동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void Example() {
  Ptr<HttpClient> http_client(new HttpClient);

  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP PUT 요청을 보냅니다.
  // Put 함수는 post data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string
  if (http_client->Put("http://example.com", data) != CURLE_OK) {
    LOG(ERROR) << "http request failure: "
               << http_client->error_message();
    return;
  }

  const http::Response &response = http_client->response();

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

C# 에서는 HttpWebRequest 클래스를 사용합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static void Example()
{
    string strUri = "http://example.com";
    System.Net.HttpWebRequest request =
      (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
    request.Method = "PUT";

    JObject data = new JObject ();
    data ["example"] = "hello world!";
    byte[] contentBytes =
        System.Text.UTF8Encoding.UTF8.GetBytes(data.ToString());

    request.ContentLength = contentBytes.Length;
    System.IO.Stream requestStream = request.GetRequestStream();
    requestStream.Write(contentBytes, 0, contentBytes.Length);
    requestStream.Close();

    System.Net.HttpWebResponse response =
      (System.Net.HttpWebResponse)request.GetResponse();

    if (response.StatusCode != HttpStatusCode.OK) {
      Log.Warning("http request failure");
      return;
    }

    System.IO.Stream respStream = response.GetResponseStream();
    System.IO.StreamReader streamReader =
      new System.IO.StreamReader(respStream, System.Text.Encoding.Default);
    string strResult = streamReader.ReadToEnd ();

    Log.Info ("Response: {0}", strResult);

    // 만약 Json 기반의 RESTful API라면 아래를 참고합니다.
    //  JToken token = JToken.Parse (strResult);
    //  if (token is JObject) {
    //    JObject jsonResponse = token.ToObject<JObject>();
    //    Log.Info ("Response: {0}", jsonResponse.ToString());
    //  } else if (token is JArray) {
    //    JArray jsonResponse = token.ToJArray ();
    //    foreach(JObject obj in jsonResponse)
    //    {
    //      Log.Info ("Response: {0}", obj.ToString());
    //    }
    //  }
}
비동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void OnResponseReceived(const CURLcode code, const string &error_message,
                        const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure: " << error_message;
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void Example() {
  Ptr<HttpClient> http_client(new HttpClient);

  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP PUT 요청을 보냅니다.
  // PutAsync 함수는 post data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string
  http_client->PutAsync2("http://example.com", data, OnResponseReceived);
}

C#에서는 HttpWebRequest 클래스와 AsyncCallback 클래스를 통해 비동기 방식의 HTTP API 통신을 구현할 수 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  public static void OnResponseReceived(IAsyncResult result)
  {
      System.Net.HttpWebResponse response =
          (result.AsyncState as HttpWebRequest).EndGetResponse (result)
              as HttpWebResponse;

      if (response.StatusCode != HttpStatusCode.OK) {
          Log.Error("http request failure");
          return;
      }

      System.IO.Stream respStream = response.GetResponseStream();
      System.IO.StreamReader streamReader =
          new System.IO.StreamReader(
              respStream, System.Text.Encoding.Default);
      string strResult = streamReader.ReadToEnd();

      Log.Info ("Response: {0}", strResult);

      // 만약 Json 기반의 RESTful API라면 아래를 참고합니다.
      //  JToken token = JToken.Parse (strResult);
      //  if (token is JObject) {
      //    JObject jsonResponse = token.ToObject<JObject>();
      //    Log.Info ("Response: {0}", jsonResponse.ToString());
      //  } else if (token is JArray) {
      //    JArray jsonResponse = token.ToJArray ();
      //    foreach(JObject obj in jsonResponse)
      //    {
      //      Log.Info ("Response: {0}", obj.ToString());
      //    }
      //  }
  }

  public static void Example()
  {
      string strUri = "http://example.com";
      System.Net.HttpWebRequest request =
        (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
      request.Method = "PUT";

      JObject data = new JObject ();
      data ["example"] = "hello world!";
      byte[] contentBytes =
          System.Text.UTF8Encoding.UTF8.GetBytes(data.ToString());

      request.ContentLength = contentBytes.Length;
      System.IO.Stream requestStream = request.GetRequestStream();
      requestStream.Write(contentBytes, 0, contentBytes.Length);
      requestStream.Close();

      request.BeginGetResponse(new AsyncCallback(OnResponseReceived), request);
  }

예제: DELETE 메소드

동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void Example() {
  Ptr<HttpClient> http_client(new HttpClient);

  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP DELETE 요청을 보냅니다.
  // Delete 함수는 delete data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string
  if (http_client->Delete("http://example.com", data) != CURLE_OK) {
    LOG(ERROR) << "http request failure: "
               << http_client->error_message();
    return;
  }

  const http::Response &response = http_client->response();

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

C# 에서는 HttpWebRequest 클래스를 사용합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static void Example()
{
    string strUri = "http://example.com";
    System.Net.HttpWebRequest request =
      (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
    request.Method = "DELETE";

    JObject data = new JObject ();
    data ["example"] = "hello world!";
    byte[] contentBytes =
        System.Text.UTF8Encoding.UTF8.GetBytes(data.ToString());

    request.ContentLength = contentBytes.Length;
    System.IO.Stream requestStream = request.GetRequestStream();
    requestStream.Write(contentBytes, 0, contentBytes.Length);
    requestStream.Close();

    System.Net.HttpWebResponse response =
      (System.Net.HttpWebResponse)request.GetResponse();

    if (response.StatusCode != HttpStatusCode.OK) {
      Log.Warning("http request failure");
      return;
    }

    System.IO.Stream respStream = response.GetResponseStream();
    System.IO.StreamReader streamReader =
      new System.IO.StreamReader(respStream, System.Text.Encoding.Default);
    string strResult = streamReader.ReadToEnd ();

    Log.Info ("Response: {0}", strResult);

    // 만약 Json 기반의 RESTful API라면 아래를 참고합니다.
    //  JToken token = JToken.Parse (strResult);
    //  if (token is JObject) {
    //    JObject jsonResponse = token.ToObject<JObject>();
    //    Log.Info ("Response: {0}", jsonResponse.ToString());
    //  } else if (token is JArray) {
    //    JArray jsonResponse = token.ToJArray ();
    //    foreach(JObject obj in jsonResponse)
    //    {
    //      Log.Info ("Response: {0}", obj.ToString());
    //    }
    //  }
}
비동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void OnResponseReceived(const CURLcode code, const string &error_message,
                        const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure: " << error_message;
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void Example() {
  Ptr<HttpClient> http_client(new HttpClient);

  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP DELETE 요청을 보냅니다.
  // DeleteAsync 함수는 delete data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string, curl_httppost
  http_client->DeleteAsync2("http://example.com", data, OnResponseReceived);
}

C#에서는 HttpWebRequest 클래스와 AsyncCallback 클래스를 통해 비동기 방식의 HTTP API 통신을 구현할 수 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  public static void OnResponseReceived(IAsyncResult result)
  {
      System.Net.HttpWebResponse response =
          (result.AsyncState as HttpWebRequest).EndGetResponse (result)
              as HttpWebResponse;

      if (response.StatusCode != HttpStatusCode.OK) {
          Log.Error("http request failure");
          return;
      }

      System.IO.Stream respStream = response.GetResponseStream();
      System.IO.StreamReader streamReader =
          new System.IO.StreamReader(
              respStream, System.Text.Encoding.Default);
      string strResult = streamReader.ReadToEnd();

      Log.Info ("Response: {0}", strResult);

      // 만약 Json 기반의 RESTful API라면 아래를 참고합니다.
      //  JToken token = JToken.Parse (strResult);
      //  if (token is JObject) {
      //    JObject jsonResponse = token.ToObject<JObject>();
      //    Log.Info ("Response: {0}", jsonResponse.ToString());
      //  } else if (token is JArray) {
      //    JArray jsonResponse = token.ToJArray ();
      //    foreach(JObject obj in jsonResponse)
      //    {
      //      Log.Info ("Response: {0}", obj.ToString());
      //    }
      //  }
  }

  public static void Example()
  {
      string strUri = "http://example.com";
      System.Net.HttpWebRequest request =
        (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUri);
      request.Method = "DELETE";

      JObject data = new JObject ();
      data ["example"] = "hello world!";
      byte[] contentBytes =
          System.Text.UTF8Encoding.UTF8.GetBytes(data.ToString());

      request.ContentLength = contentBytes.Length;
      System.IO.Stream requestStream = request.GetRequestStream();
      requestStream.Write(contentBytes, 0, contentBytes.Length);
      requestStream.Close();

      request.BeginGetResponse(new AsyncCallback(OnResponseReceived), request);
  }

HTTP Client Pool

HTTP 연결을 재활용하여 사용할 수 있도록 제공하는 인터페이스입니다. HttpClient 를 사용할 경우 매 요청마다

  1. DNS resolution

  2. TCP 연결

  3. TLS 연결(HTTPS)

  4. 요청

  5. 응답

의 과정을 거치게 됩니다. 이 때 Pool 을 만들어서 HTTP 연결을 재활용 하면 1, 2, 3 과정을 생략하여 게임 서버와 요청을 처리하는 웹 서버의 부하를 줄일 수 있습니다.

MANIFEST 설정

HttpClientPool 기능을 사용하기 위해서는 아래와 같이 MANIFEST 파일에 HttpClientPool 콤포넌트를 추가해야 합니다.

1
2
3
4
5
...
"HttpClientPool": {
  "http_client_pool_max_recycle_interval_in_sec": 3
},
...

이 콤포넌트의 설정값에 대한 설명은 HttpClientPool 을 참고해 주세요.

Note

HttpClientPool 은 C++ 버전만 제공됩니다.

HTTP 호스트 별 클라이언트 개수 확인

현재 Pool 에 등록되어 있는 호스트 별 클라이언트의 개수를 확인할 수 있는 인터페이스 입니다.

static size_t GetSize(const string &host);
static void GetSizeAll(std::vector<std::pair<string/*host*/, size_t/*size*/> > *out);

헤더 설정

헤더를 지정하려면 설정하고자 하는 헤더 값을 헤더맵으로 지정한 후, 메소드 호출 시 url 다음 인자로 함께 넘겨 줍니다. 아래는 헤더를 지정하여 GET 메소드를 호출하는 방법입니다.

typedef std::map<string /*key*/, string /*value*/> HeaderMap;

...
void Example() {
  HttpClientPool::HeaderMap headers;
  headers.insert(std::make_pair("Content-Type", "application/json"));
  headers.insert(std::make_pair("...", "..."));

  http::Response response;
  if (HttpClientPool::Get("http://example.com", headers, &response) != CURL_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }
  ...
}

각 메소드 사용에 대한 구체적인 예제를 계속해서 설명합니다.

예제: GET 메소드

동기 방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
void Example() {
  http::Response response;
  if (HttpClientPool::Get("http://example.com", &response) != CURL_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}
비동기 방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
void OnResponseReceived(const CURLcode code, const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void Example() {
  HttpClientPool::GetAsync("http://example.com", OnResponseReceived);
}

예제: POST 메소드

동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Example() {
  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP POST 요청을 보냅니다.
  // Post 함수는 post data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string, curl_httppost
  http::Response response;
  if( HttpClientPool::Post("http://example.com", data, &response) != CURLE_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}
비동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void OnResponseReceived(const CURLcode code, const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void Example() {
  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP POST 요청을 보냅니다.
  // PostAsync 함수는 post data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string, curl_httppost
  HttpClientPool::PostAsync("http://example.com", data, OnResponseReceived);
}

예제: PUT 메소드

동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Example() {
  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP PUT 요청을 보냅니다.
  // Put 함수는 put data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string
  http::Response response;
  if (HttpClientPoot::Put("http://example.com", data, &response) != CURLE_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}
비동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void OnResponseReceived(const CURLcode code, const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void Example() {
  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP PUT 요청을 보냅니다.
  // PutAsync 함수는 put data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string
  HttpClientPool::PostAsync("http://example.com", data, OnResponseReceived);
}

예제: DELETE 메소드

동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Example() {
  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP DELETE 요청을 보냅니다.
  // Delete 함수는 put data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string
  http::Response response;
  if (HttpClientPoot::Delete("http://example.com", data, &response) != CURLE_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}
비동기방식
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void OnResponseReceived(const CURLcode code, const http::Response &response) {
  if (code != CURLE_OK) {
    LOG(ERROR) << "http request failure";
    return;
  }

  if (response.status_code != http::kOk) {
    LOG(WARNING) << "status code: " << response.status_code;
  }

  LOG(INFO) << "body: " << response.body;

  // 만약 Json 기반의 RESTful API 라면 아래를 참고합니다.
  // Json r;
  // r.FromString(response.body);
}

void Example() {
  Json data;
  data["example"] = "hello world!";

  // http://example.com 으로 HTTP DELETE 요청을 보냅니다.
  // DeleteAsync 함수는 delete data 인자로 다음과 같은 type 을 받습니다.
  //  - fun::Json, std::string
  HttpClientPool::DeleteAsync("http://example.com", data, OnResponseReceived);
}