간단한 GET 형식으로 사용할 때는 WWW가 편하고 좋다.
하지만 일부 사이트는 User-Agent 값을 읽어 막는 곳이 있었다.
그래서 User-Agent값을 수정하려고 했지만, 지원하지 않았다.
아래 코드는 User-Agent값 수정이 자유롭고,
동기모드 사용시, 유니티 메인쓰레드가 멈춰 게임 화면이 멈추게 되는데,
Coroutine과 HttpWebResponse 비동기 모드를 사용하면 멈춤 현상을 해결할 수 있다.
비동기 모드 사용시 주의 점은 메인쓰레드가 아닌 곳에서 유니티 오브젝트 또는 함수를 사용하면
get_isActiveAndEnabled can only be called from the main thread. 같은 오류가 발생한다.
제대로 하려면 쓰레드간 통신을 위한 큐를 만들고
메인쓰레드가 그 큐를 읽어 처리를 하면 되겠지만,
간단히 웹에 대한 결과만 얻어오면 되니, 그냥 간단하게 만들었다.
코루틴 비동기 함수가 끝났는지를 체크할 수 있는 로컬 변수 isDone을 정의해 사용했다.
비동기 함수 완료 콜백함수(타 쓰레드)에서 가져올 데이터가 있다면 로컬 변수에 저장 시켜야 한다.
여기서는 text에 저장시켰다.
text에 저장시킨 후, 즉 사용할 모든 데이터를 저장시킨 후,
맨 마지막에 isDone을 true값으로 변경해야 원자성을 보장할 수 있겠다.
아래 코드를 참고해 적절히 수정해서 쓰면 좋을 것 같다.
[SerializeField]
Text m_text;
IEnumerator TestWWW(string url)
{
bool isDone = false;
string text = null;
/*
using (WWW www = new WWW(url))
{
yield return www;
m_text.text = string.IsNullOrEmpty(www.error) ? "no error" : www.error;
m_text.text = www.text;
}*/
// for https
ServicePointManager.ServerCertificateValidationCallback = delegate
{
return true;
};
/* // sync
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.UserAgent = "";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
m_text.text = reader.ReadToEnd();
}
*/
// async
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.BeginGetResponse(new AsyncCallback((IAsyncResult iarres) => {
try
{
using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.EndGetResponse(iarres))
{
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
{
// can only be called from the main thread
//m_text.text = streamReader.ReadToEnd();
text = streamReader.ReadToEnd();
isDone = true;
}
response.Close();
}
}
catch (Exception e)
{
}
}), null);
while(!isDone)
yield return null;
m_text.text = text;
}