1. UnityWebRequest
UnityWebRequest는 Unity 클라이언트에서 웹 서버 측으로 HTTP 요청을 보내고 response를 받도록 도와주는 API 입니다.
공식으로 제공해주는 API인 만큼 Unity에서사용하기 좋게끔 정리가 되어있고 단순한 string부터 JSON 데이터, 이미지 파일 등 다양한 정보를 주고받을 수 있습니다.
2. 사용 방법
2-1. GET Method (서버에서 데이터 불러오기)
1) 전체 스크립트
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class WebRequestManager : MonoBehaviour
{
private string uri;
private void Start()
{
StartCoroutine(GetRequest(uri));
}
IEnumerator GetRequest(string uri)
{
using (UnityWebRequest request = UnityWebRequest.Get(uri))
{
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log("Response: " + request.downloadHandler.text);
}
else
{
Debug.LogError("Error: " + request.error);
}
}
}
}
2) 코드 상세 설명
using UnityEngine.Networking;
using System.Collections;
UnityWebRequest를 사용하여 웹 서버에 요청을 보내기 위해 필요한 namespace들 입니다.
UnityWebRequest, DownloadHandler, UploadHandler를 사용하기 위해 UnityEngine.Networking을 선언합니다.
Coroutine, IEnumerator를 사용하기 위해 System.Collections을 선언합니다.
StartCoroutine(GetRequest(uri));
...
IEnumerator GetRequest(string uri)
HTTP Request를 전송할 URI을 매개변수로 전달하여 해당 URI로 GET 요청을 전송합니다.
* GetRequest를 Coroutine 함수로 작성한 이유는 서버나 네트워크의 상황에 따라 응답 시간이 달라질 수 있으므로 응답을 기다리는 동안 게임이 멈추지 않도록 하기위해 비동기로 동작하도록 구현하는 것이 좋습니다.
using (UnityWebRequest request = UnityWebRequest.Get(uri))
UnityWebRequest 객체를 생성할 때 using 구문을 사용하면 request가 요청을 마친 후, 자동으로 메모리를 해제하기 때문에 메모리 누수를 방지할 수 있습니다.
* using 문을 사용하지 않으면 GC(Garbage Collector)가 돌기 전까지 메모리를 낭비하게 됩니다.
yield return request.SendWebRequest();
GetRequest를 Coroutine 함수로 만든 이유입니다. yield return을 사용하여 SendWebRequest()가 response를 return 받아올 때 까지 대기합니다.
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log("Response: " + request.downloadHandler.text);
}
else
{
Debug.LogError("Error: " + request.error);
}
request가 받아온 response에 대한 처리입니다.
request.result는 request가 받아온 response가 정상적인지 상태정보를 가지고 있습니다. request.result 가 UnityWebRequest.Result.Success 일 경우 정상적으로 response를 받아왔다는 의미입니다.
서버에서 데이터를 정상적으로 받아왔다면 요청한 데이터가 request.downloadHandler.text 에 들어있고 이 데이터를 필요에 따라 형 변환하여 사용할 수 있습니다.
서버에서 데이터를 정상적으로 불러오지 못했다면 (request.result 가 UnityWebRequest.Result.Success 와 다르다면) 요청이 실패한 이유가 request.error에 들어오게 됩니다.
* errorcode는 400 또는 500대의 숫자를 포함하고 있을텐데, 보통 이 숫자가 400대라면 클라이언트 측 이슈, 500대라면 서버 측 이슈에 의한 에러입니다.
2-2. POST Method (서버로 데이터 보내기)
1) 전체 스크립트
IEnumerator PostRequest(string uri, string jsonData)
{
using (UnityWebRequest request = new UnityWebRequest(uri, "POST"))
{
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonData);
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log("Response: " + request.downloadHandler.text);
}
else
{
Debug.LogError("Error: " + request.error);
}
}
}
2) 코드 상세 설명
GetRequest와 차이점을 위주로 알아보겠습니다.
IEnumerator PostRequest(string uri, string jsonData)
GetRequest의 경우 매개변수(parameter)를 uri 하나만 받지만 PostRequest는 uri와 전송할 데이터(위 스크립트 에서는 jsonData)까지 2개의 매개변수를 받습니다.
GetRequest는 데이터를 조회하는 용도로 사용되기 때문에 데이터를 찾아갈 uri만 알면 되지만 PostRequest는 서버에 데이터를 추가하거나 수정해야하기 때문에 요청할 정보를 가지고 있어야합니다.
* HTTP 프로토콜은 텍스트를 기반으로 통신하기 때문에 전송할 정보들을 Object나 Array의 형태가 아닌 string 형태로 변환하여 보내줘야합니다.
using (UnityWebRequest request = new UnityWebRequest(uri, "POST"))
GetRequest에서 UnityWebRequest.Get(uri)로 객체를 생성하는 것처럼 Post도 UnityWebRequest.Post(uri, string)로 생성하는 방법도 있지만 이 방법으로 구현할 경우 json 형식이 아닌 form 형식으로 전송하기 때문에 form 데이터를 직접 구현해야하는 번거로움이 있습니다. 그렇기 때문에 Post 요청을 구현할 때는 UnityWebRequest(uri, "POST")를 사용하는 편이 유리합니다.
byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonData);
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
Post 요청 시 body에 들어갈 정보를 구성하는 부분입니다. 한 줄 씩 맡은 역할을 알아보겠습니다.
1 - UnityWebRequest는 body 데이터를 byte 배열로 처리하기 때문에 jsonData를 인코딩하여 byte배열로 재구성합니다.
2 - 인코딩된 byte 배열을 request의 uploadHandler에 넣습니다.
3 - response의 downloadHandler를 읽어오기 위해서 DownloadHandlerBuffer() 객체를 생성합니다.
4 - request가 가지고 있는 데이터가 json 형식임을 명시합니다.
이후 코드들은 GETRequest와 동일하며 마찬가지로 받아온 데이터를 형 변환하여 사용할 수 있습니다.
3. 중요한 점 정리
- Request함수를 Coroutine 함수로 만들고 yield return을 사용하여 SendWebRequest()가 response를 return 받아오는 동안 게임의 진행이 막히지 않도록 구현해야합니다.
- using 구문을 사용하여 request가 요청을 마친 후, 자동으로 메모리를 해제하도록 구현하면 메모리 누수를 방지할 수 있습니다.
'공부 정리 > Unity' 카테고리의 다른 글
Coroutine 으로 구현하는 비동기 프로그래밍 (Async/Await와 비교) (4) | 2025.03.23 |
---|---|
Synchronous(동기), Asynchronous(비동기), Parallel(병렬) 비교 (2) | 2025.03.20 |