Skip to content

Instantly share code, notes, and snippets.

@yychen
Last active September 24, 2018 11:33
Show Gist options
  • Save yychen/2337da1e5a5d69dd336231c755b5dac1 to your computer and use it in GitHub Desktop.
Save yychen/2337da1e5a5d69dd336231c755b5dac1 to your computer and use it in GitHub Desktop.
APIService.cs
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