Untiy在一些情况下(比如公司后台没有https证书之类的)需要用到C# 中的HttpClient来进行网络请求。为此特封装了一份相关的方法以做到对网络请求更加方便的调用
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using Newtonsoft.Json;
public class NetworkUtil
{
[Serializable]
public class ResponseData
{
public int ret;
public string msg;
}
public static string requestHead = (TestManager.Instance.product && !StatusManager.UseTestUrlRoot) ? GameConfig.URL_PRODUCT_ROOT : GameConfig.URL_TEST_ROOT;
public static string MD5Key = GameConfig.MD5_Key;
class AcceptAllCertificatesSignedWithASpecificKeyPublicKey : CertificateHandler
{
protected override bool ValidateCertificate(byte[] certificateData)
{
return true;
}
}
#region 公有方法
/// <summary>
/// 有没有连接网络
/// </summary>
/// <returns></returns>
public static bool InternetConnected()
{
return Application.internetReachability != NetworkReachability.NotReachable;
}
/// <summary>
/// 下载图片
/// </summary>
/// <param name="url"></param>
/// <returns>返回Sprite</returns>
public static async Task<Sprite> SendGetImageRequest(string url)
{
HttpClient httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(0, 0, 20);
HttpResponseMessage httpResponseMessage = await httpClient.GetAsync(url);
if (httpResponseMessage != null)
{
MolaLog.Log("NetworkUtil", "", "Download Success:{0}", url);
byte[] imageBytes = httpResponseMessage.Content.ReadAsByteArrayAsync().Result;
Texture2D tex = new Texture2D(0, 0);
tex.LoadImage(imageBytes);
tex.Apply();
if (tex != null)
{
return Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
}
}
return null;
}
/// <summary>
/// 下载图片(回调返回byte数组)
/// </summary>
/// <param name="url"></param>
/// <param name="callBack"></param>
/// <param name="progressCallBack">进度回调,进度总值为100</param>
public static HttpClient SendGetImageRequest(string url, Action<byte[]> callBack)
{
HttpClient httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(0, 0, 20);
MolaLog.Log("NetworkUtil", "", "Start Requset Image URL:{0}", url);
httpClient.GetAsync(url).ContinueWith((getTask) =>
{
try
{
MolaLog.Log("NetworkUtil", "", "Download Success:{0}", url);
MolaLog.Log("NetworkUtil", "", "Download Size:{0}", getTask.Result.Content.Headers.ContentLength);
byte[] imageBytes = getTask.Result.Content.ReadAsByteArrayAsync().Result;
callBack?.Invoke(imageBytes);
}
catch (HttpRequestException exception)
{
MolaLog.Log("NetworkUtil", "", "Request failed:{0}", exception);
callBack?.Invoke(null);
}
catch (Exception exception)
{
MolaLog.Log("NetworkUtil", "", "Request failed:{0}", exception);
callBack?.Invoke(null);
}
});
return httpClient;
}
/// <summary>
/// 发送Get请求
/// </summary>
/// <param name="url"></param>
/// <param name="callBack"></param>
public static void SendGetRequest(string url, Action<ResponseData> callBack, int retry = 0, float retryDuration = 0)
{
SendGetRequest<ResponseData>(url, callBack, retry, retryDuration);
}
/// <summary>
/// 发送Get请求
/// </summary>
/// <param name="url"></param>
/// <param name="callBack"></param>
public static void SendGetRequest<T>(string url, Action<T> callBack, int retry = 0, float retryDuration = 0) where T : ResponseData
{
HttpClient httpClient = new HttpClient();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
httpClient.DefaultRequestHeaders.Accept.Clear();
MolaLog.Log("NetworkUtil", "", "Send request:{0}", url);
Request(httpClient, url, null, callBack, retry, retryDuration); ;
}
/// <summary>
/// 发送Post请求(默认)
/// </summary>
/// <param name="url"></param>
/// <param name="param"></param>
/// <param name="callBack"></param>
public static void SendPostRequest(string url, object param, Action<ResponseData> callBack, int retry = 0, float retryDuration = 0)
{
SendPostRequest<ResponseData>(url, param, callBack, retry, retryDuration);
}
/// <summary>
/// 发送Post请求
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="param"></param>
/// <param name="callBack"></param>
/// <param name="backDataType"></param>
public static void SendPostRequest<T>(string url, object param, Action<T> callBack, int retry = 0, float retryDuration = 0) where T : ResponseData
{
SendPostRequest(url, param, null, callBack, retry, retryDuration);
}
/// <summary>
/// 发送Post请求
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="param"></param>
/// <param name="callBack"></param>
/// <param name="backDataType"></param>
public static void SendPostRequest<T>(string url, object param, Dictionary<string, string> headers, Action<T> callBack, int retry = 0, float retryDuration = 0) where T : ResponseData
{
HttpClient httpClient = new HttpClient();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
httpClient.DefaultRequestHeaders.Accept.Clear();
MolaLog.Log("NetworkUtil", "", "Request to {0}", url);
HttpContent content;
if (param is string)
{
MolaLog.Log("NetworkUtil", "", "Json: {0}", param);
content = new StringContent((string)param, System.Text.Encoding.UTF8, "application/json");
}
else if (param is HttpContent)
{
content = (HttpContent)param;
}
else if (param is Dictionary<string, object>)
{
string jsonStr = JsonConvert.SerializeObject(param);
content = new StringContent(jsonStr, System.Text.Encoding.UTF8, "application/json");
}
else
{
MolaLog.Log("NetworkUtil", "", "Invalid param type: {0}", param.GetType());
return;
}
if (headers != null)
{
foreach (KeyValuePair<string, string> pair in headers)
{
content.Headers.Add(pair.Key, pair.Value);
}
}
Request(httpClient, url, content, callBack, retry, retryDuration);
}
#endregion
#region 私有方法
/// <summary>
/// 开始请求及重新请求
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="httpClient"></param>
/// <param name="url"></param>
/// <param name="content"></param>
/// <param name="callBack"></param>
/// <param name="retry"></param>
/// <param name="retryDuration"></param>
private static void Request<T>(HttpClient httpClient, string url, HttpContent content, Action<T> callBack, int retry = 0, float retryDuration = 0) where T : ResponseData
{
retry--;
Task<HttpResponseMessage> task;
if (content != null)
{
task = httpClient.PostAsync(url, content);
}
else
{
task = httpClient.GetAsync(url);
}
task.ContinueWith(
(postTask) =>
RequestCallback<T>(postTask, (responseData) =>
{
if (responseData != null)
{
callBack(responseData);
}
else
{
if (retry > -1)
{
Util.Delay(retryDuration, () => {
Request(httpClient, url, content, callBack, retry, retryDuration);
});
}
else
{
callBack(null);
}
}
})
);
}
/// <summary>
/// 请求回调处理
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="task"></param>
/// <param name="callBack"></param>
private static void RequestCallback<T>(Task<HttpResponseMessage> task, Action<T> callBack) where T : ResponseData
{
try
{
HttpResponseMessage response = task.Result;
response.EnsureSuccessStatusCode();
response.Content.ReadAsStringAsync()
.ContinueWith(
(readTask) =>
{
MolaLog.Log("NetworkUtil", "", "Request success:{0}", readTask.Result);
T responseData = JsonConvert.DeserializeObject<T>(readTask.Result);
MolaLog.Log("NetworkUtil", "", "Result:{0}", responseData.ret);
MolaLog.Log("NetworkUtil", "", "Message:{0}", responseData.msg);
callBack?.Invoke(responseData);
});
}
catch (HttpRequestException exception)
{
MolaLog.Log("NetworkUtil", "", "Request failed:{0}", exception);
callBack?.Invoke(null);
}
catch (Exception exception)
{
MolaLog.Log("NetworkUtil", "", "Request failed:{0}", exception);
callBack?.Invoke(null);
}
}
#endregion
}