[C# 서버] Account Server에서 로그인을 위한 API를 만들었는데 클라이언트에서 이를 사용하려면 어떻게 해야할까?
먼저 웹서버에 요청을 전담할 클래스를 하나 만드는 방법이 있다. 특정 사이트에 바로 요청을 하는 것 보다는 POST 전송을 하는 클래스도 하나 만들고 2개의 클래스를 사용하는 것이 효율적이다.
클라이언트에서 요청전송도 중요하지만 돌아온 응답에 대해서 어떻게 행동할지도 중요하다. 요청부터 응답까지의 시간동안 기다리는 것도 하나의 방법이지만 유니티에는 Coroutine
이라는 기능을 지원한다. 즉, 요청하고 yield return한다면 아래 코드는 응답이후에 실행이 된다는 확신을 가질 수 있다.
public class WebManager
{
public string BaseUrl { get; set; } = "https://localhost:5001/api";
public void SendPostRequest<T>(string url, object obj, Action<T> res)
{
Managers.Instance.StartCoroutine(CoSendWebRequest(url, "POST", obj, res));
}
IEnumerator CoSendWebRequest<T>(string url, string method, object obj, Action<T> res)
{
string sendUrl = $"{BaseUrl}/{url}";
byte[] jsonByte = null;
if (obj != null)
{
string jsonStr = JsonUtility.ToJson(obj);
jsonByte = Encoding.UTF8.GetBytes(jsonStr);
}
using (var uwr = new UnityWebRequest(sendUrl, method))
{
uwr.uploadHandler = new UploadHandlerRaw(jsonByte);
uwr.downloadHandler = new DownloadHandlerBuffer();
uwr.SetRequestHeader("Content-Type", "application/json");
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log(uwr.error);
}
else
{
T resObj = JsonUtility.FromJson<T>(uwr.downloadHandler.text);
res.Invoke(resObj);
}
}
}
}
유니티에서 POST요청을 보내는 기능을 구현하기 위해 보낼 주소와 클래스외부에서 사용할 인터페이스가 필요하다.
public string BaseUrl { get; set; } = "https://localhost:5001/api";
public void SendPostRequest<T>(string url, object obj, Action<T> res)
{
Managers.Instance.StartCoroutine(CoSendWebRequest(url, "POST", obj, res));
}
POST 요청을 보내는 Coroutine을 정의하는데 입력으로는 보낼 url과 전송방법, 전송할 데이터, 응답시 동작할 콜백함수를 받는다.
IEnumerator CoSendWebRequest<T>(string url, string method, object obj, Action<T> res)
{
string sendUrl = $"{BaseUrl}/{url}";
byte[] jsonByte = null;
if (obj != null)
{
string jsonStr = JsonUtility.ToJson(obj);
jsonByte = Encoding.UTF8.GetBytes(jsonStr);
}
웹 요청을 보내기 위해 유니티에서 제공하는 UnityWebRequest
를 사용한다. 보낼 주소와 보낼 방식(POST)를 명시하고 입출력 버퍼, 요청형식(Json)을 설정한다. 요청을 전송하면서 yield return을 하면 밑의 부분은 응답이 오고 실행이 된다.
만약 성공적으로 데이터가 도착했다면 Json으로 파싱하고 데이터에 대한 콜백함수를 실행시킨다.
using (var uwr = new UnityWebRequest(sendUrl, method))
{
uwr.uploadHandler = new UploadHandlerRaw(jsonByte);
uwr.downloadHandler = new DownloadHandlerBuffer();
uwr.SetRequestHeader("Content-Type", "application/json");
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log(uwr.error);
}
else
{
T resObj = JsonUtility.FromJson<T>(uwr.downloadHandler.text);
res.Invoke(resObj);
}
}
WebPacket은 위에서 구현한 WebManager를 사용하는 클래스로 회원가입, 로그인같은 트랜잭션 단위의 기능을 처리하는 함수들을 가지고 있다. 여기서 주의해야 할 점은 WebManager를 구현할 때 return type을 Generic으로 이후에 지정할 수 있도록 하였는데, 회원가입요청을 보낼때는 회원가입응답패킷을 Generic을 명시하고 로그인요청을 보낼때는 로그인응답패킷을 명시해야한다는 점이다.
public class WebPacket
{
public static void SendCreateAccount(string account, string password)
{
CreateAccountPacketReq packet = new CreateAccountPacketReq()
{
AccountName = account,
Password = password
};
Managers.Web.SendPostRequest<CreateAccountPacketRes>("account/create", packet, (res) =>
{
Debug.Log(res.CreateOk);
});
}
public static void SendLoginAccount(string account, string password)
{
LoginAccountPacketReq packet = new LoginAccountPacketReq()
{
AccountName = account,
Password = password
};
Managers.Web.SendPostRequest<LoginAccountPacketRes>("account/login", packet, (res) =>
{
Debug.Log(res.LoginOk);
});
}
}