Last active
September 24, 2018 11:33
-
-
Save yychen/2337da1e5a5d69dd336231c755b5dac1 to your computer and use it in GitHub Desktop.
APIService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using RSG; | |
using UnityEngine; | |
using UnityEngine.Networking; | |
public class RequestException : Exception { | |
public UnityWebRequest Request { get; set; } | |
public RequestException(string message, UnityWebRequest request) : base(message) { | |
Request = request; | |
} | |
} | |
public class APIService : Singleton<APIService> { | |
public void Request(string url, Action<string> successCallback, Action<Exception> failureCallback, string method = UnityWebRequest.kHttpVerbGET, List<IMultipartFormSection> multipartFormSection = null) { | |
StartCoroutine(DoRequest(url, method, multipartFormSection, successCallback, failureCallback)); | |
} | |
public void Request(string url, Promise<string> promise, string method = UnityWebRequest.kHttpVerbGET, List<IMultipartFormSection> multipartFormSection = null) { | |
StartCoroutine(DoRequest(url, method, multipartFormSection, (data) => | |
{ | |
promise.Resolve(data); | |
}, (ex) => | |
{ | |
promise.Reject(ex); | |
})); | |
} | |
public void RequestTexture(string url, Promise<Texture> promise) { | |
StartCoroutine(DoRequest(url, (data) => { | |
promise.Resolve(data); | |
}, (ex) => { | |
promise.Reject(ex); | |
})); | |
} | |
public IPromise<string> Request(string url, string method = UnityWebRequest.kHttpVerbGET, List<IMultipartFormSection> multipartFormSection = null) | |
{ | |
var promise = new Promise<string>(); | |
Request(url, promise, method, multipartFormSection); | |
return promise; | |
} | |
public void RequestPrimarySecondary(string primary, string secondary, | |
Promise<string> promise, | |
string method = UnityWebRequest.kHttpVerbGET, | |
List<IMultipartFormSection> multipartFormSection = null) { | |
Debug.Log($"[APIService] Primary and secondary Request call.\nPrimary: {primary}\nSecondary: {secondary}"); | |
var primaryPromise = new Promise<string>(); | |
var secondaryPromise = new Promise<string>(); | |
primaryPromise.Then(data => { | |
promise.Resolve(data); | |
}).Catch(ex => { | |
Debug.LogError($"[APIService] Primary failed, try secondary {secondary}...\nPrimary Failed ({primary}) {DumpException((RequestException)ex)}"); | |
Request(secondary, secondaryPromise, method, multipartFormSection); | |
}); | |
secondaryPromise.Then(data => { | |
promise.Resolve(data); | |
}).Catch(ex => { | |
Debug.LogError($"[APIService] Secondary failed...\n{DumpException((RequestException)ex)}"); | |
promise.Reject(ex); | |
}); | |
Request(primary, primaryPromise, method, multipartFormSection); | |
} | |
IEnumerator DoRequest(string url, string method = UnityWebRequest.kHttpVerbGET, List<IMultipartFormSection> multipartFormSection = null, Action<string> successCallback = null, Action<Exception> failureCallback = null) { | |
UnityWebRequest request = new UnityWebRequest(url); | |
Debug.Log($"[APIService] url: {method} {url}"); | |
request.method = method; | |
request.downloadHandler = new DownloadHandlerBuffer(); | |
if (multipartFormSection != null) { | |
byte[] boundary = UnityWebRequest.GenerateBoundary(); | |
byte[] formSections = UnityWebRequest.SerializeFormSections(multipartFormSection, boundary); | |
byte[] terminate = System.Text.Encoding.UTF8.GetBytes(String.Concat("\r\n--", System.Text.Encoding.UTF8.GetString(boundary), "--")); | |
byte[] body = new byte[formSections.Length + terminate.Length]; | |
Buffer.BlockCopy(formSections, 0, body, 0, formSections.Length); | |
Buffer.BlockCopy(terminate, 0, body, formSections.Length, terminate.Length); | |
UploadHandler uploader = new UploadHandlerRaw(body); | |
uploader.contentType = "multipart/form-data; boundary=\"" + System.Text.Encoding.UTF8.GetString(boundary) + "\""; | |
request.uploadHandler = uploader; | |
request.useHttpContinue = false; | |
request.chunkedTransfer = false; | |
} | |
else { | |
// lower timeout for non-file uploading requests | |
request.timeout = 5; | |
} | |
yield return request.SendWebRequest(); | |
if (request.isNetworkError || request.isHttpError) { | |
failureCallback(new RequestException(request.error, request)); | |
} | |
else if (request.responseCode != 200) { | |
// another failure Callback | |
Debug.LogError(request.downloadHandler.text); | |
failureCallback(new RequestException(request.downloadHandler.text, request)); | |
} | |
else { | |
Debug.Log($"[APIService] Got result:\n{request.downloadHandler.text}"); | |
successCallback(request.downloadHandler.text); | |
} | |
} | |
IEnumerator DoRequest(string url, Action<Texture> successCallback = null, Action<Exception> failureCallback = null) { | |
UnityWebRequest request = new UnityWebRequest(url); | |
Debug.Log($"[APIService] url: {url}"); | |
var handler = new DownloadHandlerTexture(true); | |
request.downloadHandler = handler; | |
request.timeout = 5; | |
yield return request.SendWebRequest(); | |
if (request.isNetworkError || request.isHttpError) { | |
failureCallback(new RequestException(request.error, request)); | |
} | |
else if (request.responseCode != 200) { | |
// another failure Callback | |
Debug.LogError(request.downloadHandler.text); | |
failureCallback(new RequestException(request.downloadHandler.text, request)); | |
} | |
else { | |
Debug.Log($"[APIService] Got result:\n{request.downloadHandler.text}"); | |
successCallback(handler.texture); | |
} | |
} | |
public string DumpException(RequestException ex) { | |
string output; | |
output = $"Report>>> isNetworkError: {ex.Request.isNetworkError}, isHttpError: {ex.Request.isHttpError}"; | |
if (ex.Request.isHttpError) { | |
output += $", Return code: {ex.Request.responseCode}\nResponse: \n{ex.Request.downloadHandler.text}"; | |
} | |
output += $", {ex}"; | |
return output; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment