1. 程式人生 > >HTTP接口訪問類

HTTP接口訪問類

enume length 地址映射 red ring 訪問類 nal account attribute

using UnityEngine;
using System.Collections;
using System;
using System.Text;
using LitJson;
using System.Collections.Generic;
using NetworkMessages;
using System.Reflection;

/// <summary>
/// HTTP接口訪問類
/// </summary>
public class WebAccess : MonoBehaviour
{
/// <summary>
/// 接口分類與後臺服務基地址映射關系
/// </summary>
private static Dictionary<string, string> apiTypeToServerBaseUrlMap;

private static void InitializeApiTypeToServerUrlMap()
{
apiTypeToServerBaseUrlMap = new Dictionary<string, string>
{
{ "account", "http://192.168.0.75:8990/" },
{ "logic", "http://192.168.0.75:9601/" },
{ "PENDING", "http://192.168.0.75:11001/" },
};
}
private const float timeout = 3f;
static WebAccess instance;

public static WebAccess Instance
{
get
{
if (instance == null)
{
InitializeApiMaps();
InitializeApiTypeToServerUrlMap();
GameObject go = new GameObject("WebAccess");
instance = go.AddComponent<WebAccess>();
DontDestroyOnLoad(go);
return instance;
}
else
{
return instance;
}
}
}

private string token;
private Dictionary<string, string> headersToSend = new Dictionary<string, string>();

public string Token
{
get
{
return token;
}
set
{
token = value;
Debug.Log("set token to " + value);
headersToSend["Authorization"] = token;
}
}

/// <summary>
/// HTTP接口的返回結果類型與該接口對應的名稱的字典
/// </summary>
static Dictionary<Type, string> apiNameMaps = null;
static Dictionary<Type, string> apiTypeMaps = null;

static void InitializeApiMaps()
{
apiNameMaps = new Dictionary<Type, string>();
apiTypeMaps = new Dictionary<Type, string>();
// 添加所有用到的HTTP接口的返回結果類型
Assembly current = Assembly.GetExecutingAssembly();
Type[] allTypes = current.GetTypes();
for (int i = 0; i < allTypes.Length; i++)
{
Type type = allTypes[i];
if (type.IsDefined(typeof(WebApiResultAttribute), false))
{
WebApiResultAttribute attr = type.GetCustomAttributes(typeof(WebApiResultAttribute), false)[0] as WebApiResultAttribute;
apiNameMaps.Add(type, attr.ApiName);
apiTypeMaps.Add(type, attr.ApiType);
}
}
Debug.Log("registered Web-API count: " + apiNameMaps.Count);
}

void OnDestroy()
{
instance = null;
if (apiNameMaps != null)
{
apiNameMaps.Clear();
apiNameMaps = null;
}
if (apiTypeMaps != null)
{
apiTypeMaps.Clear();
apiTypeMaps = null;
}
}

string GetApiUrlByType(Type type)
{
string apiType = apiTypeMaps[type];
string apiName = apiNameMaps[type];
return apiTypeToServerBaseUrlMap[apiType] + apiName;
}

/// <summary>
/// 執行HTTP接口
/// </summary>
/// <param name="parameters">接口所需的參數</param>
/// <param name="onSuccess">接口調用成功時回調</param>
/// <param name="onFail">接口調用失敗時的回調</param>
/// <typeparam name="TResult">該HTTP接口的返回結果類型</typeparam>
public void RunAPI<TResult>(WebApiParameter parameters, Action<WebApiResult> onSuccess, Action<WebApiError> onFail) where TResult : WebApiResult
{
DialogTipsCtrl.Instance.BeginWait();
StartCoroutine(GetData(parameters, typeof(TResult), onSuccess, onFail));
}

/// <summary>
/// 以協程方式訪問HTTP接口
/// </summary>
/// <param name="parameters">接口所需的參數</param>
/// <param name="resultType">返回結果類型</param>
/// <param name="onSuccess">接口調用成功時回調</param>
/// <param name="onFail">接口調用失敗時的回調</param>
IEnumerator GetData(WebApiParameter parameters, Type resultType, Action<WebApiResult> onSuccess, Action<WebApiError> onFail)
{
string json = JsonMapper.ToJson(parameters);
string encrypted = Web.Networking.AesBase64Encrypt.Encrypt(json);
byte[] rawData = Encoding.UTF8.GetBytes(encrypted);
string fullUrl = GetApiUrlByType(resultType);
Debug.Log("accessing " + fullUrl + " with parameters: " + json + " with rawdata: " + encrypted);
WWW www = new WWW(fullUrl, rawData, headersToSend);
float time = 0f;
float progress = 0f;
while (string.IsNullOrEmpty(www.error) && !www.isDone)
{
// 如果進度長時間不動,就累積這個時間,做超時處理。
if (www.progress != progress)
{
// 如果進度變化,重置超時計時為0
time = 0f;
progress = www.progress;
}
time += Time.deltaTime;
if (time > timeout)
{
break;
}
yield return null;
}
try
{
if (time > timeout)
{
Debug.LogError("HTTP接口訪問超時");
SafelyInvokeOnFailCallback(onFail, new WebApiError("HTTP接口訪問超時"));
}
else if (string.IsNullOrEmpty(www.error))
{
string webResult = www.text;
Debug.Log("server reply: " + www.text);
string decrypted = Web.Networking.AesBase64Encrypt.Decrypt(webResult);
Debug.Log("decrypted server reply: " + decrypted);
object obj = JsonMapper.ToObject(decrypted, resultType);
WebApiResult result = (WebApiResult)obj;
if (result.result == 0)
{
SafelyInvokeOnSuccessCallback(onSuccess, result);
}
else
{
SafelyInvokeOnFailCallback(onFail, new WebApiError(result.result));
}
}
else
{
SafelyInvokeOnFailCallback(onFail, new WebApiError(www.error));
}
}
catch (Exception e)
{
Debug.LogException(e);
SafelyInvokeOnFailCallback(onFail, new WebApiError(e));
}
finally
{
DialogTipsCtrl.Instance.EndWait();
}
}

/// <summary>
/// 安全地調用成功回調方法
/// </summary>
void SafelyInvokeOnSuccessCallback(Action<WebApiResult> onSuccess, WebApiResult result)
{
if (onSuccess != null)
{
// 包裹回調調用,可以避免因為回調本身的異常被判定為 RunAPI 的錯誤。
try
{
onSuccess(result);
}
catch (Exception e)
{
Debug.LogException(e);
}
}
}

/// <summary>
/// 安全地調用失敗回調方法
/// </summary>
void SafelyInvokeOnFailCallback(Action<WebApiError> onFail, WebApiError error)
{
if (onFail != null)
{
// 包裹回調調用,可以避免因為回調本身的異常被判定為 RunAPI 的錯誤。
try
{
onFail(error);
}
catch (Exception e)
{
Debug.LogException(e);
}
}
}

}

HTTP接口訪問類