You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1262 lines
53 KiB
1262 lines
53 KiB
using UnityEngine; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
using System; |
|
using System.Text; |
|
using BestHTTP; |
|
using Newtonsoft.Json; |
|
using System.IO; |
|
using Cysharp.Threading.Tasks; |
|
using System.Security.Cryptography; |
|
using System.Linq; |
|
using AX.MessageSystem; |
|
|
|
/// <summary> |
|
/// 服务器配置文件对应类型 |
|
/// </summary> |
|
public class ServerConfig |
|
{ |
|
public string Ip; |
|
public string Port; |
|
} |
|
|
|
/// <summary> |
|
/// 刷新令牌信息。 |
|
/// </summary> |
|
public class RefreshTokenInfo |
|
{ |
|
/// <summary> |
|
/// JWT令牌。 |
|
/// </summary> |
|
public string Token { get; set; } |
|
/// <summary> |
|
/// 刷新令牌。 |
|
/// </summary> |
|
public string RefreshToken { get; set; } |
|
} |
|
|
|
public class HTTPRequestManager : MonoBehaviour |
|
{ |
|
public static HTTPRequestManager Instance; |
|
|
|
private string baseHttpUrl = ""; |
|
|
|
public IdentityInfo identityInfo = new IdentityInfo(); //记录登录成功后的身份信息 |
|
public string userName;//记录登录成功后的用户名 |
|
|
|
private const string refreshTokenApi = "/api/Account/RefreshToken"; |
|
|
|
#region 文件下载、上传成员变量 |
|
private const int fragmentSize = 5 * 1024 * 1024;//分块大小 |
|
private const string newMultipartUploadApi = "/api/NewMultipartUpload/firetraining"; |
|
private const string completeMultipartUploadApi = "/api/CompleteMultipartUpload/firetraining"; |
|
private const string multipartUploadInfosKey = "MultipartUploadInfos"; |
|
#endregion |
|
|
|
private void Awake() |
|
{ |
|
DontDestroyOnLoad(this); |
|
Instance = this; |
|
|
|
//Json序列化全局默认设置 |
|
JsonConvert.DefaultSettings = () => new JsonSerializerSettings() |
|
{ |
|
Formatting = Formatting.Indented |
|
}; |
|
} |
|
|
|
void Start() |
|
{ |
|
if (string.IsNullOrEmpty(baseHttpUrl)) |
|
{ |
|
string filepath = Application.streamingAssetsPath + @"/ServerConfig.json"; |
|
LoadFileHelper.Instance.LoadFileStringAsync(filepath, (s) => |
|
{ |
|
ServerConfig config = JsonConvert.DeserializeObject<ServerConfig>(s); |
|
baseHttpUrl = "http://" + config.Ip + ":" + config.Port; |
|
MessageDispatcher.SendMessage("ServerConfigLoaded"); |
|
}); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 获取json数据 |
|
/// </summary> |
|
/// <typeparam name="T">返回数据类型</typeparam> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void GetJson<T>(string apiUrl, Action<T> success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Get, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
T result = JsonConvert.DeserializeObject<T>(resp.DataAsText); |
|
success?.Invoke(result); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 提交json数据 |
|
/// </summary> |
|
/// <typeparam name="TIn">提交数据类型</typeparam> |
|
/// <typeparam name="TOut">返回数据类型</typeparam> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="data">提交数据</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void PostJson<TIn, TOut>(string apiUrl, TIn data, Action<TOut> success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Post, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
TOut result = JsonConvert.DeserializeObject<TOut>(resp.DataAsText); |
|
success?.Invoke(result); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
request.SetHeader("Content-Type", "application/json; charset=UTF-8"); |
|
string json = JsonConvert.SerializeObject(data); |
|
request.RawData = Encoding.UTF8.GetBytes(json); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 提交json数据 |
|
/// </summary> |
|
/// <typeparam name="TIn">提交数据类型</typeparam> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="data">提交数据</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void PostJson<TIn>(string apiUrl, TIn data, Action success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Post, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
success?.Invoke(); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
request.SetHeader("Content-Type", "application/json; charset=UTF-8"); |
|
string json = JsonConvert.SerializeObject(data); |
|
request.RawData = Encoding.UTF8.GetBytes(json); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 提交json数据 |
|
/// </summary> |
|
/// <typeparam name="TOut">返回数据类型</typeparam> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void PostJson<TOut>(string apiUrl, Action<TOut> success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Post, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
TOut result = JsonConvert.DeserializeObject<TOut>(resp.DataAsText); |
|
success?.Invoke(result); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 提交json数据 |
|
/// </summary> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void PostJson(string apiUrl, Action success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Post, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
success?.Invoke(); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 修改json数据 |
|
/// </summary> |
|
/// <typeparam name="TIn">修改数据类型</typeparam> |
|
/// <typeparam name="TOut">返回数据类型</typeparam> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="data">修改数据</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void PatchJson<TIn, TOut>(string apiUrl, TIn data, Action<TOut> success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Patch, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
TOut result = JsonConvert.DeserializeObject<TOut>(resp.DataAsText); |
|
success?.Invoke(result); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
request.SetHeader("Content-Type", "application/json; charset=UTF-8"); |
|
string json = JsonConvert.SerializeObject(data); |
|
request.RawData = Encoding.UTF8.GetBytes(json); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 修改json数据 |
|
/// </summary> |
|
/// <typeparam name="TIn">修改数据类型</typeparam> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="data">修改数据</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void PatchJson<TIn>(string apiUrl, TIn data, Action success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Patch, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
success?.Invoke(); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
request.SetHeader("Content-Type", "application/json; charset=UTF-8"); |
|
string json = JsonConvert.SerializeObject(data); |
|
request.RawData = Encoding.UTF8.GetBytes(json); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 删除json数据 |
|
/// </summary> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void DeleteJson(string apiUrl, Action success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Delete, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
success?.Invoke(); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 删除json数据 |
|
/// </summary> |
|
/// <typeparam name="TIn">提交数据类型</typeparam> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="data">提交数据</param> |
|
/// <param name="success">请求成功回调</param> |
|
/// <param name="error">请求错误回调</param> |
|
public void DeleteJson<TIn>(string apiUrl, TIn data, Action success, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
{ |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
} |
|
|
|
HTTPRequest request = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Delete, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
success?.Invoke(); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
error?.Invoke((int)HTTPRequestStates.Aborted, "Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
request.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
request.SetHeader("Content-Type", "application/json; charset=UTF-8"); |
|
string json = JsonConvert.SerializeObject(data); |
|
request.RawData = Encoding.UTF8.GetBytes(json); |
|
|
|
request.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 文件下载:分块下载,支持下载的断点续传 |
|
/// </summary> |
|
/// <param name="apiUrl"> API URL</param> |
|
/// <param name="isCache">是否缓存到本地</param> |
|
/// <param name="isFileChange">服务器文件是否变动</param> |
|
/// <param name="complete">下载完成回调</param> |
|
/// <param name="progress">下载进度回调</param> |
|
/// <param name="error">下载错误回调</param> |
|
/// <param name="localPath">本地缓存路径:包含文件名、扩展名的相对路径</param> |
|
/// <param name="fileBytes">内存中缓存文件字节流的数组</param> |
|
/// /// <param name="reqCallBack">传出HTTPRequest实例的回调:方便上层缓存请求来中止请求(request.Abort())</param> |
|
public void FileDownload(string apiUrl, bool isCache, bool isFileChange, Action complete, Action<float> progress = null, Action<int, string> error = null, string localPath = null, List<byte> fileBytes = null, Action<HTTPRequest> reqCallBack = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
|
|
if (isCache) |
|
{ |
|
if (string.IsNullOrEmpty(localPath)) |
|
{ |
|
throw new ArgumentNullException($"本地缓存路径:{localPath}无效!"); |
|
} |
|
else |
|
{ |
|
try |
|
{ |
|
string fileName = Path.GetFileName(localPath); |
|
if (string.IsNullOrEmpty(fileName)) |
|
{ |
|
if (fileName == null) |
|
throw new ArgumentException($"本地缓存路径:{localPath}无效!"); |
|
if (fileName == "") |
|
throw new ArgumentException($"本地缓存路径:{localPath}无效!"); |
|
} |
|
} |
|
catch (Exception e) |
|
{ |
|
throw new ArgumentException("本地缓存路径无效!", "localPath", e); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
if (fileBytes == null) |
|
{ |
|
throw new ArgumentNullException("不缓存本地时,必须传入fileBytes参数!"); |
|
} |
|
} |
|
|
|
string tempFilePath = ""; |
|
if (isCache) |
|
tempFilePath = $"{localPath}.temp"; |
|
|
|
long downloadFileTotalLength = -1; |
|
long downloadStartedAt = 0; |
|
long downloadedLength = 0; |
|
|
|
HTTPRequest downloadRequest = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Get, (req, resp) => |
|
{ |
|
var fs = req.Tag as FileStream; |
|
|
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
if ((downloadStartedAt + downloadedLength) >= downloadFileTotalLength) |
|
{ |
|
if (fs != null) { fs.Close(); fs.Dispose(); } |
|
|
|
if (isCache) |
|
{ |
|
if (File.Exists(localPath)) |
|
File.Delete(localPath); |
|
File.Move(tempFilePath, localPath); |
|
} |
|
|
|
complete?.Invoke(); |
|
} |
|
else |
|
{ |
|
req.SetRangeHeader(downloadStartedAt + downloadedLength, downloadStartedAt + downloadedLength + fragmentSize); |
|
req.Send(); |
|
} |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, string.Format("Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
|
|
if (fs != null) { fs.Close(); fs.Dispose(); } |
|
|
|
downloadRequest = null; |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
|
|
if (fs != null) { fs.Close(); fs.Dispose(); } |
|
|
|
downloadRequest = null; |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
|
|
if (fs != null) { fs.Close(); fs.Dispose(); } |
|
|
|
downloadRequest = null; |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
|
|
if (fs != null) { fs.Close(); fs.Dispose(); } |
|
|
|
downloadRequest = null; |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
|
|
if (fs != null) { fs.Close(); fs.Dispose(); } |
|
|
|
downloadRequest = null; |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
downloadRequest = null; |
|
}); |
|
reqCallBack?.Invoke(downloadRequest); |
|
|
|
downloadRequest.OnHeadersReceived += (req, resp, headers) => |
|
{ |
|
var range = resp.GetRange(); |
|
if (range != null) |
|
downloadFileTotalLength = range.ContentLength; |
|
|
|
if (!isCache && fileBytes.Count == 0) |
|
{ |
|
fileBytes.Capacity = (int)downloadFileTotalLength; |
|
} |
|
}; |
|
|
|
if (isCache) |
|
{ |
|
if (!isFileChange) |
|
{ |
|
if (File.Exists(tempFilePath)) |
|
{ |
|
FileInfo fileInfo = new FileInfo(tempFilePath); |
|
downloadStartedAt = fileInfo.Length; |
|
fileInfo = null; |
|
} |
|
else |
|
{//下载了部分需要继续断点下载的情况下,下载了部分的本地临时文件被误删,则需要从新下载整个文件 |
|
downloadStartedAt = 0; |
|
} |
|
} |
|
else |
|
{ |
|
downloadStartedAt = 0; |
|
if (File.Exists(tempFilePath)) |
|
{ |
|
File.Delete(tempFilePath); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
downloadStartedAt = fileBytes.Count; |
|
} |
|
|
|
downloadRequest.OnDownloadProgress += (req, downloaded, downloadLength) => |
|
{ |
|
double downloadPercent = ((downloadStartedAt + downloadedLength + downloaded) / (double)downloadFileTotalLength); |
|
progress?.Invoke((float)downloadPercent); |
|
}; |
|
|
|
downloadRequest.OnStreamingData += (req, resp, dataFragment, dataFragmentLength) => |
|
{ |
|
if (isCache) |
|
{ |
|
if (resp.IsSuccess) |
|
{ |
|
string directory = Path.GetDirectoryName(tempFilePath); |
|
if (!Directory.Exists(directory)) |
|
Directory.CreateDirectory(directory); |
|
|
|
var fs = req.Tag as FileStream; |
|
if (fs == null) |
|
req.Tag = fs = new FileStream(tempFilePath, FileMode.Append, FileAccess.Write, FileShare.Read); |
|
|
|
fs.Write(dataFragment, 0, dataFragmentLength); |
|
downloadedLength += dataFragmentLength; |
|
} |
|
} |
|
else |
|
{ |
|
if (resp.IsSuccess) |
|
{ |
|
fileBytes.AddRange(dataFragment.Skip(0).Take(dataFragmentLength).ToArray()); |
|
downloadedLength += dataFragmentLength; |
|
} |
|
} |
|
|
|
return true; |
|
}; |
|
|
|
downloadRequest.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
downloadRequest.SetRangeHeader(downloadStartedAt, downloadStartedAt + fragmentSize); |
|
downloadRequest.DisableCache = true; |
|
downloadRequest.StreamFragmentSize = fragmentSize; |
|
|
|
downloadRequest.Send(); |
|
} |
|
|
|
/// <summary> |
|
/// 文件上传:分块上传,支持上传的断点续传 |
|
/// </summary> |
|
/// <param name="apiUrl">API URL</param> |
|
/// <param name="objectName">服务端桶下的路径</param> |
|
/// <param name="filePath">上传文件在本地的路径</param> |
|
/// <param name="complete">上传完成回调</param> |
|
/// <param name="progress">上传进度回调</param> |
|
/// <param name="error">上传错误回调</param> |
|
/// <param name="reqCallBack">传出HTTPRequest实例的回调:方便上层缓存请求来中止请求(request.Abort())</param> |
|
public async UniTaskVoid FileUploadAsync(string apiUrl, string objectName, string filePath, Action complete, Action<float> progress = null, Action<int, string> error = null, Action<HTTPRequest> reqCallBack = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
|
|
if (string.IsNullOrEmpty(objectName)) |
|
{ |
|
throw new ArgumentNullException($"文件路径:{objectName}无效!"); |
|
} |
|
else |
|
{ |
|
try |
|
{ |
|
string fileName = Path.GetFileName(objectName); |
|
if (string.IsNullOrEmpty(fileName)) |
|
{ |
|
if (fileName == null) |
|
throw new ArgumentException($"本地缓存路径:{objectName}无效!"); |
|
if (fileName == "") |
|
throw new ArgumentException($"本地缓存路径:{objectName}无效!"); |
|
} |
|
} |
|
catch (Exception e) |
|
{ |
|
throw new ArgumentException("本地缓存路径无效!", "objectName", e); |
|
} |
|
} |
|
|
|
if (string.IsNullOrEmpty(filePath)) |
|
{ |
|
throw new ArgumentNullException($"文件路径:{filePath}无效!"); |
|
} |
|
else |
|
{ |
|
try |
|
{ |
|
string fileName = Path.GetFileName(filePath); |
|
if (string.IsNullOrEmpty(fileName)) |
|
{ |
|
if (fileName == null) |
|
throw new ArgumentException($"本地缓存路径:{filePath}无效!"); |
|
if (fileName == "") |
|
throw new ArgumentException($"本地缓存路径:{filePath}无效!"); |
|
} |
|
} |
|
catch (Exception e) |
|
{ |
|
throw new ArgumentException("本地缓存路径无效!", "filePath", e); |
|
} |
|
} |
|
|
|
string md5; |
|
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) |
|
{ |
|
md5 = HashAlgorithm<MD5>.ComputeHash(fs); |
|
} |
|
string uploadFileName = Path.GetFileName(objectName); |
|
|
|
var savedMultipartUploadInfos = GetMultipartUploadInfos(objectName); |
|
NewMultipartUploadResult newMultipartUploadResult = new NewMultipartUploadResult(); |
|
MultipartUploadInfos multipartUploadInfos = new MultipartUploadInfos(); |
|
if (objectName == savedMultipartUploadInfos.newMultipartUploadResult.objectName && md5 == savedMultipartUploadInfos.md5) |
|
{ |
|
newMultipartUploadResult = savedMultipartUploadInfos.newMultipartUploadResult; |
|
} |
|
else |
|
{ |
|
string directoryName = Path.GetDirectoryName(objectName); |
|
string newMultipartUploadUrl = $"{newMultipartUploadApi}/{directoryName}?keepOriginalName={true}&fileName={uploadFileName}"; |
|
//初始化分块上传事件 |
|
newMultipartUploadResult = await NewMultipartUpload(newMultipartUploadUrl, error); |
|
|
|
multipartUploadInfos.newMultipartUploadResult = newMultipartUploadResult; |
|
multipartUploadInfos.md5 = md5; |
|
|
|
SaveMultipartUploadInfos(objectName, $"{JsonConvert.SerializeObject(multipartUploadInfos)}"); |
|
savedMultipartUploadInfos = GetMultipartUploadInfos(objectName); |
|
} |
|
|
|
|
|
//分块上传文件处理 |
|
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) |
|
{ |
|
string multipartUploadUrl; |
|
List<PartInfo> partInfos = new List<PartInfo>(); |
|
double uploadPercent; |
|
|
|
//上传文件总长度 |
|
long uploadFileTotalSize = fileStream.Length; |
|
//上传文件剩余总长度 |
|
long uploadFileRemainTotalSize = fileStream.Length; |
|
//分块总数 |
|
int fragmentTotalCount = (int)Math.Ceiling((double)uploadFileTotalSize / fragmentSize); |
|
//当前上传分块数 |
|
int currentUploadFragmentCount = 0; |
|
//上传开始位置 |
|
long uploadStartAt = 0; |
|
//缓存分块读取的字节流数组 |
|
byte[] bytes = new byte[fragmentSize]; |
|
//实际读取长度 |
|
int bytesLength = 0; |
|
|
|
long uploadProcessedBytes = savedMultipartUploadInfos.uploadProcessedBytes; |
|
if (uploadProcessedBytes > 0) |
|
{ |
|
uploadFileRemainTotalSize = uploadFileTotalSize - uploadProcessedBytes; |
|
currentUploadFragmentCount = (int)Math.Ceiling((double)uploadProcessedBytes / fragmentSize); |
|
uploadStartAt = uploadProcessedBytes; |
|
fileStream.Position = uploadStartAt; |
|
|
|
partInfos = savedMultipartUploadInfos.partInfos; |
|
} |
|
else |
|
DeleteKeys(objectName); |
|
|
|
while (currentUploadFragmentCount < fragmentTotalCount) |
|
{ |
|
if (uploadFileRemainTotalSize < fragmentSize) |
|
{ |
|
bytes = new byte[uploadFileRemainTotalSize]; |
|
bytesLength = fileStream.Read(bytes, 0, Convert.ToInt32(uploadFileRemainTotalSize)); |
|
} |
|
else |
|
{ |
|
bytes = new byte[fragmentSize]; |
|
bytesLength = fileStream.Read(bytes, 0, fragmentSize); |
|
} |
|
|
|
multipartUploadUrl = $"{apiUrl}?uploadId={newMultipartUploadResult.uploadId}&partNumber={currentUploadFragmentCount + 1}"; |
|
//上传文件分块数据 |
|
PartInfo partInfo = await MultipartUpload(multipartUploadUrl, bytes, uploadFileName, error, reqCallBack); |
|
partInfos.Add(partInfo); |
|
|
|
uploadFileRemainTotalSize -= bytesLength; |
|
currentUploadFragmentCount++; |
|
uploadStartAt += bytesLength; |
|
fileStream.Position = uploadStartAt; |
|
|
|
multipartUploadInfos.uploadProcessedBytes = uploadStartAt; |
|
multipartUploadInfos.partInfos = partInfos; |
|
SaveMultipartUploadInfos(objectName, $"{JsonConvert.SerializeObject(multipartUploadInfos)}"); |
|
|
|
uploadPercent = uploadStartAt / (double)fileStream.Length; |
|
progress?.Invoke((float)uploadPercent); |
|
} |
|
|
|
//分块上传完成处理 |
|
if (currentUploadFragmentCount == fragmentTotalCount) |
|
{ |
|
string completeMultipartUploadUrl = $"{completeMultipartUploadApi}/{objectName}?uploadId={newMultipartUploadResult.uploadId}"; |
|
await CompleteMultipartUpload(completeMultipartUploadUrl, partInfos, complete, error); |
|
DeleteKeys(objectName); |
|
} |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 初始化分块上传事件 |
|
/// </summary> |
|
/// <param name="url"></param> |
|
/// <param name="error"></param> |
|
/// <returns></returns> |
|
private async UniTask<NewMultipartUploadResult> NewMultipartUpload(string url, Action<int, string> error) |
|
{ |
|
HTTPRequest req = new HTTPRequest(new Uri(baseHttpUrl + url), HTTPMethods.Post); |
|
req.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
|
|
try |
|
{ |
|
var json = await req.GetAsStringAsync(); |
|
NewMultipartUploadResult newMultipartUploadResult = JsonConvert.DeserializeObject<NewMultipartUploadResult>(json); |
|
return newMultipartUploadResult; |
|
} |
|
catch (AsyncHTTPException ex) |
|
{ |
|
if (ex.StatusCode != 0) |
|
{ |
|
|
|
error?.Invoke(ex.StatusCode, string.Format("Status Code: {0}-{1} Message: {2}", |
|
ex.StatusCode, |
|
ex.Message, |
|
ex.Content)); |
|
} |
|
else |
|
{ |
|
error?.Invoke((int)req.State, ex.Message); |
|
} |
|
|
|
throw ex; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 上传文件分块数据 |
|
/// </summary> |
|
/// <param name="url"></param> |
|
/// <param name="bytes"></param> |
|
/// <param name="error"></param> |
|
/// <param name="reqCallBack"></param> |
|
/// <returns></returns> |
|
private async UniTask<PartInfo> MultipartUpload(string url, byte[] bytes, string fileName, Action<int, string> error, Action<HTTPRequest> reqCallBack = null) |
|
{ |
|
HTTPRequest req = new HTTPRequest(new Uri(baseHttpUrl + url), HTTPMethods.Post); |
|
req.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
req.AddBinaryData("file", bytes, fileName, "application/octet-stream"); |
|
|
|
reqCallBack?.Invoke(req); |
|
|
|
try |
|
{ |
|
var json = await req.GetAsStringAsync(); |
|
PartInfo partInfo = JsonConvert.DeserializeObject<PartInfo>(json); |
|
return partInfo; |
|
} |
|
catch (AsyncHTTPException ex) |
|
{ |
|
if (ex.StatusCode != 0) |
|
{ |
|
error?.Invoke(ex.StatusCode, string.Format("Status Code: {0}-{1} Message: {2}", |
|
ex.StatusCode, |
|
ex.Message, |
|
ex.Content)); |
|
} |
|
else |
|
{ |
|
error?.Invoke((int)req.State, ex.Message); |
|
} |
|
|
|
throw ex; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 完成分块上传事件 |
|
/// </summary> |
|
/// <param name="url"></param> |
|
/// <param name="partInfos"></param> |
|
/// <param name="complete"></param> |
|
/// <param name="error"></param> |
|
/// <returns></returns> |
|
private async UniTask CompleteMultipartUpload(string url, List<PartInfo> partInfos, Action complete, Action<int, string> error) |
|
{ |
|
HTTPRequest req = new HTTPRequest(new Uri(baseHttpUrl + url), HTTPMethods.Post); |
|
req.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
req.SetHeader("Content-Type", "application/json; charset=UTF-8"); |
|
List<PartNumberETag> partNumberETags = new List<PartNumberETag>(); |
|
foreach (var partInfo in partInfos) |
|
{ |
|
partNumberETags.Add(new PartNumberETag() { partNumber = partInfo.partNumber, eTag = partInfo.eTag }); |
|
} |
|
string jsonData = JsonConvert.SerializeObject(partNumberETags); |
|
req.RawData = Encoding.UTF8.GetBytes(jsonData); |
|
|
|
try |
|
{ |
|
await req.GetAsStringAsync(); |
|
|
|
complete?.Invoke(); |
|
} |
|
catch (AsyncHTTPException ex) |
|
{ |
|
if (ex.StatusCode != 0) |
|
{ |
|
error?.Invoke(ex.StatusCode, string.Format("Status Code: {0}-{1} Message: {2}", |
|
ex.StatusCode, |
|
ex.Message, |
|
ex.Content)); |
|
} |
|
else |
|
{ |
|
error?.Invoke((int)req.State, ex.Message); |
|
} |
|
|
|
throw ex; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 保存文件分块上传信息 |
|
/// </summary> |
|
/// <param name="objectName"></param> |
|
/// <param name="str"></param> |
|
private void SaveMultipartUploadInfos(string objectName, string str) |
|
{ |
|
PlayerPrefs.SetString(objectName + multipartUploadInfosKey, str); |
|
} |
|
|
|
/// <summary> |
|
/// 获取保存的文件分块上传信息 |
|
/// </summary> |
|
/// <param name="objectName"></param> |
|
/// <returns></returns> |
|
private MultipartUploadInfos GetMultipartUploadInfos(string objectName) |
|
{ |
|
string str = PlayerPrefs.GetString(objectName + multipartUploadInfosKey, ""); |
|
if (!string.IsNullOrEmpty(str)) |
|
{ |
|
var multipartUploadInfos = JsonConvert.DeserializeObject<MultipartUploadInfos>(str); |
|
return multipartUploadInfos; |
|
} |
|
else |
|
{ |
|
return new MultipartUploadInfos(); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 删除保存的文件分块上传信息 |
|
/// </summary> |
|
/// <param name="objectName"></param> |
|
private void DeleteKeys(string objectName) |
|
{ |
|
PlayerPrefs.DeleteKey(objectName + multipartUploadInfosKey); |
|
PlayerPrefs.Save(); |
|
} |
|
|
|
/// <summary> |
|
/// 文件夹复制 |
|
/// </summary> |
|
/// <param name="apiUrl"></param> |
|
/// <param name="complete"></param> |
|
/// <param name="error"></param> |
|
public void FileDirectoryCopy(string apiUrl, Action<ListObjectsResult> complete, Action<int, string> error = null) |
|
{ |
|
if (string.IsNullOrEmpty(apiUrl)) |
|
throw new ArgumentNullException($"API URL:{apiUrl}无效!"); |
|
|
|
HTTPRequest directoryCopyRequest = new HTTPRequest(new Uri(baseHttpUrl + apiUrl), HTTPMethods.Put, (req, resp) => |
|
{ |
|
switch (req.State) |
|
{ |
|
case HTTPRequestStates.Finished: |
|
if (resp.IsSuccess) |
|
{ |
|
ListObjectsResult result = JsonConvert.DeserializeObject<ListObjectsResult>(resp.DataAsText); |
|
complete?.Invoke(result); |
|
} |
|
else |
|
{ |
|
Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}", |
|
resp.StatusCode, |
|
resp.Message, |
|
resp.DataAsText)); |
|
error?.Invoke(resp.StatusCode, JsonConvert.DeserializeObject<ProblemDetails>(resp.DataAsText).detail); |
|
} |
|
break; |
|
case HTTPRequestStates.Error: |
|
Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception")); |
|
error?.Invoke((int)HTTPRequestStates.Error, "Request Finished with Error!"); |
|
break; |
|
case HTTPRequestStates.Aborted: |
|
Debug.LogWarning("Request Aborted!"); |
|
break; |
|
case HTTPRequestStates.ConnectionTimedOut: |
|
Debug.LogError("Connection Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.ConnectionTimedOut, "Connection Timed Out!"); |
|
break; |
|
case HTTPRequestStates.TimedOut: |
|
Debug.LogError("Processing the request Timed Out!"); |
|
error?.Invoke((int)HTTPRequestStates.TimedOut, "Processing the request Timed Out!"); |
|
break; |
|
} |
|
}); |
|
|
|
directoryCopyRequest.SetHeader("Authorization", "Bearer " + identityInfo.token); |
|
|
|
directoryCopyRequest.Send(); |
|
} |
|
public string GetBaseHttpUrl() |
|
{ |
|
return baseHttpUrl; |
|
} |
|
|
|
#region 刷新令牌 |
|
/// <summary> |
|
/// 启动刷新令牌计时器 |
|
/// </summary> |
|
public void StartTimer() |
|
{ |
|
RefreshTokenInfo refreshTokenInfo = new RefreshTokenInfo(); |
|
refreshTokenInfo.Token = identityInfo.token; |
|
refreshTokenInfo.RefreshToken = identityInfo.refreshToken; |
|
|
|
StartCoroutine(Timer(refreshTokenInfo)); |
|
} |
|
|
|
/// <summary> |
|
/// 计时器:根据登录成功后,服务端返回的身份信息中的token过期时间(分钟),定时提前1分钟来刷新token |
|
/// </summary> |
|
/// <param name="refreshTokenInfo">刷新令牌信息</param> |
|
/// <returns></returns> |
|
private IEnumerator Timer(RefreshTokenInfo refreshTokenInfo) |
|
{ |
|
while (true) |
|
{ |
|
yield return new WaitForSeconds((float)(identityInfo.expires - 1) * 60); |
|
PostJson<RefreshTokenInfo, IdentityInfo>( |
|
refreshTokenApi, refreshTokenInfo, |
|
RefreshTokenSuccessed, |
|
RefreshTokenError |
|
); |
|
} |
|
} |
|
|
|
private void RefreshTokenSuccessed(IdentityInfo identityInfo) |
|
{ |
|
this.identityInfo = identityInfo; |
|
//如果处于管理员界面处理页面token刷新 |
|
//AdminManager.Instance.RefreshWebToke(); |
|
} |
|
|
|
private void RefreshTokenError(int responseCode, string errorMsg) |
|
{ |
|
Debug.LogError($"刷新身份错误:{responseCode},{errorMsg}"); |
|
} |
|
#endregion |
|
}
|
|
|