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.
1263 lines
53 KiB
1263 lines
53 KiB
8 months ago
|
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
|
||
|
}
|