RequestComponent.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. using LitJson;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Threading.Tasks;
  5. using UnityEngine;
  6. using UnityEngine.Events;
  7. using UnityEngine.Networking;
  8. namespace WS
  9. {
  10. ///<summary>Header 实体</summary>
  11. public class ResponseHeader
  12. {
  13. ///<summary>名称(Key)</summary>
  14. public string Name { get; set; }
  15. ///<summary>值</summary>
  16. public string Value { get; set; }
  17. }
  18. [ObjectSystem]
  19. public class RequestComponentAwakeSystem : AwakeSystem<RequestComponent>
  20. {
  21. public override void Awake(RequestComponent self)
  22. {
  23. self.Awake();
  24. }
  25. }
  26. ///<summary>Web请求管理</summary>
  27. public class RequestComponent : SingleComponent<RequestComponent>
  28. {
  29. //请求超时时间
  30. public const int OutTime = 10;
  31. //所有Header
  32. private readonly Dictionary<string, ResponseHeader> Headers = new Dictionary<string, ResponseHeader>();
  33. //默认Header
  34. private readonly List<string> DefaultHeaders = new List<string>();
  35. //错误码
  36. private readonly static Dictionary<int, string> ErrorCode = new Dictionary<int, string>();
  37. public void Awake()
  38. {
  39. AddErrorCode(500, "服务器内部错误!");
  40. AddErrorCode(405, "接口错误!");
  41. AddErrorCode(404, "请求无效!");
  42. AddErrorCode(403, "权限不足!");
  43. AddErrorCode(401, "未登录!");
  44. AddErrorCode(0, "请求超时,服务器未响应!");
  45. }
  46. #region -- Header --
  47. /// <summary>添加/修改 Header</summary>
  48. /// <param name="name">名称</param>
  49. /// <param name="key">键</param>
  50. /// <param name="value">值</param>
  51. /// <param name="isdefault">设置为默认Header,回自动在请求时添加</param>
  52. public void AddHeader(string name, string key, string value, bool isdefault = false)
  53. {
  54. if (!Headers.ContainsKey(name))
  55. {
  56. ResponseHeader header = new ResponseHeader();
  57. Headers.Add(name, header);
  58. }
  59. Headers[name].Name = key;
  60. Headers[name].Value = value;
  61. if (isdefault)
  62. {
  63. if (!DefaultHeaders.Contains(name))
  64. {
  65. DefaultHeaders.Add(name);
  66. }
  67. }
  68. }
  69. /// <summary>移除 Header</summary>
  70. /// <param name="name">名称</param>
  71. public void RemoveHeader(string name)
  72. {
  73. if (Headers.ContainsKey(name))
  74. {
  75. Headers.Remove(name);
  76. if (DefaultHeaders.Contains(name))
  77. {
  78. DefaultHeaders.Remove(name);
  79. }
  80. }
  81. }
  82. /// <summary>移除所有 Header</summary>
  83. public void RemoveAllHeader()
  84. {
  85. Headers.Clear();
  86. DefaultHeaders.Clear();
  87. }
  88. /// <summary>获取 Header</summary>
  89. /// <param name="name">名称</param>
  90. public ResponseHeader GetHeader(string name)
  91. {
  92. if (Headers.ContainsKey(name))
  93. {
  94. return Headers[name];
  95. }
  96. return null;
  97. }
  98. /// <summary>设置 Header</summary>
  99. /// <param name="header">存储header的名称</param>
  100. /// <param name="webrequest">请求代理</param>
  101. public void SetHeader(string[] header, UnityWebRequest webrequest)
  102. {
  103. for (int i = 0; i < DefaultHeaders.Count; i++)
  104. {
  105. ResponseHeader rh = GetHeader(DefaultHeaders[i]);
  106. webrequest.SetRequestHeader(rh.Name, rh.Value);
  107. }
  108. if (header.Length > 0)
  109. {
  110. for (int i = 0; i < header.Length; i++)
  111. {
  112. if (!DefaultHeaders.Contains(header[i]))
  113. {
  114. ResponseHeader rh = GetHeader(header[i]);
  115. webrequest.SetRequestHeader(rh.Name, rh.Value);
  116. }
  117. }
  118. }
  119. }
  120. #endregion
  121. #region -- ErrorCode--
  122. ///<summary>添加请求错误拦截状态码(只有异步请求有效)</summary>
  123. ///<param name="code">状态码</param>
  124. ///<param name="msg">提示消息</param>
  125. public void AddErrorCode(int code, string msg)
  126. {
  127. if (!ErrorCode.ContainsKey(code))
  128. {
  129. ErrorCode.Add(code, msg);
  130. }
  131. }
  132. #endregion
  133. #region -- Get --
  134. /// <summary>Get 请求</summary>
  135. /// <typeparam name="T">请求返回的数据类型</typeparam>
  136. /// <param name="url">请求地址</param>
  137. /// <param name="oncallback">请求回调</param>
  138. /// <param name="header">头</param>
  139. public static void Get<T>(string url, UnityAction<ResponseOutput<T>> oncallback, params string[] header)
  140. {
  141. TimerComponent.Instance.StartCoroutine(MonoGet<T>(url, oncallback, header));
  142. }
  143. /// <summary>Get 请求文件</summary>
  144. /// <param name="url">请求地址</param>
  145. /// <param name="oncallback">请求回调</param>
  146. /// <param name="header">头</param>
  147. public static void Get(string url, UnityAction<byte[]> oncallback, params string[] header)
  148. {
  149. TimerComponent.Instance.StartCoroutine(MonoGetFile(url, oncallback, header));
  150. }
  151. ///<summary>Get 请求</summary>
  152. /// <typeparam name="T">请求返回的数据类型</typeparam>
  153. /// <param name="url">请求地址</param>
  154. /// <param name="header">头</param>
  155. public static async Task<ResponseOutput<T>> GetAsync<T>(string url, params string[] header)
  156. {
  157. RequestAsync request = ComponentFactory.Create<RequestAsync>();
  158. await request.GetAsync(url, header);
  159. ResponseOutput<T> output = ParseRequest<T>(request);
  160. return output;
  161. }
  162. ///<summary>Get 请求文件</summary>
  163. /// <param name="url">请求地址</param>
  164. /// <param name="header">头</param>
  165. public static async Task<byte[]> GetAsync(string url, params string[] header)
  166. {
  167. RequestAsync request = ComponentFactory.Create<RequestAsync>();
  168. await request.GetAsync(url, header);
  169. if (!string.IsNullOrEmpty(request.Request.error))
  170. {
  171. #if UNITY_EDITOR||DEBUG_MODEL
  172. Log.LogError($"HTTP请求错误!地址:{request.Request.uri} 消息:{request.Request.error} Code:{request.Request.responseCode}");
  173. #endif
  174. }
  175. else
  176. {
  177. #if UNITY_EDITOR||DEBUG_MODEL
  178. Log.LogDebug(request.Request.uri + " 数据Length:" + request.Request.downloadHandler.data.Length, WSLogType.绿);
  179. #endif
  180. }
  181. byte[] buffer = request.Request.downloadHandler.data;
  182. request.Dispose();
  183. return buffer;
  184. }
  185. //Get 请求
  186. private static IEnumerator MonoGet<T>(string url, UnityAction<ResponseOutput<T>> oncallback, params string[] header)
  187. {
  188. UnityWebRequest webrequest = UnityWebRequest.Get(url);
  189. webrequest.timeout = OutTime;
  190. Instance.SetHeader(header, webrequest);
  191. yield return webrequest.SendWebRequest();
  192. ParseRequest(oncallback, webrequest);
  193. }
  194. //Get 请求文件
  195. private static IEnumerator MonoGetFile(string url, UnityAction<byte[]> oncallback, params string[] header)
  196. {
  197. UnityWebRequest webrequest = UnityWebRequest.Get(url);
  198. webrequest.timeout = OutTime;
  199. Instance.SetHeader(header, webrequest);
  200. yield return webrequest.SendWebRequest();
  201. ResponseOutput<byte[]> output = new ResponseOutput<byte[]>();
  202. if (!string.IsNullOrEmpty(webrequest.error))
  203. {
  204. #if UNITY_EDITOR || DEBUG_MODEL
  205. Log.LogError($"HTTP请求错误!地址:{webrequest.uri} 消息:{webrequest.error} Code:{webrequest.responseCode}");
  206. #endif
  207. }
  208. else
  209. {
  210. #if UNITY_EDITOR || DEBUG_MODEL
  211. Log.LogDebug(webrequest.uri + " 数据Length:" + webrequest.downloadHandler.data.Length, WSLogType.绿);
  212. #endif
  213. oncallback.Invoke(webrequest.downloadHandler.data);
  214. }
  215. webrequest.Dispose();
  216. }
  217. #endregion
  218. #region -- Post --
  219. #region -- Json --
  220. /// <summary>Post Json提交</summary>
  221. /// <typeparam name="T">请求返回的数据类型</typeparam>
  222. /// <param name="url">请求地址</param>
  223. /// <param name="json">Json 数据</param>
  224. /// <param name="oncallback">请求回调</param>
  225. /// <param name="header">头</param>
  226. public static void Post<T>(string url, string json, UnityAction<ResponseOutput<T>> oncallback, params string[] header)
  227. {
  228. TimerComponent.Instance.StartCoroutine(MonoPost<T>(url, json, oncallback, header));
  229. }
  230. ///<summary>Post请求</summary>
  231. /// <typeparam name="T">请求返回的数据类型</typeparam>
  232. /// <param name="url">请求地址</param>
  233. /// <param name="json">Json 数据</param>
  234. /// <param name="header">头</param>
  235. public static async Task<ResponseOutput<T>> PostAsync<T>(string url, string json, params string[] header)
  236. {
  237. RequestAsync request = ComponentFactory.Create<RequestAsync>();
  238. await request.PostAsync(url, json, header);
  239. ResponseOutput<T> output = ParseRequest<T>(request);
  240. return output;
  241. }
  242. //Post Json提交
  243. private static IEnumerator MonoPost<T>(string url, string json, UnityAction<ResponseOutput<T>> oncallback, params string[] header)
  244. {
  245. byte[] postBytes = System.Text.Encoding.Default.GetBytes(json);
  246. UnityWebRequest webrequest = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST);
  247. webrequest.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
  248. webrequest.SetRequestHeader("Content-Type", "application/json");
  249. webrequest.timeout = OutTime;
  250. Instance.SetHeader(header, webrequest);
  251. yield return webrequest.SendWebRequest();
  252. ParseRequest(oncallback, webrequest);
  253. }
  254. #endregion
  255. #region -- Form --
  256. /// <summary>Post 表单提交</summary>
  257. /// <typeparam name="T">请求返回的数据类型</typeparam>
  258. /// <param name="url">请求地址</param>
  259. /// <param name="form">表单</param>
  260. /// <param name="oncallback">请求回调</param>
  261. /// <param name="header">头</param>
  262. public static void Post<T>(string url, WWWForm form, UnityAction<ResponseOutput<T>> oncallback, params string[] header)
  263. {
  264. TimerComponent.Instance.StartCoroutine(MonoPost<T>(url, form, oncallback, header));
  265. }
  266. ///<summary>Post请求</summary>
  267. /// <typeparam name="T">请求返回的数据类型</typeparam>
  268. /// <param name="url">请求地址</param>
  269. /// <param name="form">表单</param>
  270. /// <param name="header">头</param>
  271. public static async Task<ResponseOutput<T>> PostAsync<T>(string url, WWWForm form, params string[] header)
  272. {
  273. RequestAsync request = ComponentFactory.Create<RequestAsync>();
  274. await request.PostAsync(url, form, header);
  275. ResponseOutput<T> output = ParseRequest<T>(request);
  276. return output;
  277. }
  278. //Post 表单提交
  279. private static IEnumerator MonoPost<T>(string url, WWWForm form, UnityAction<ResponseOutput<T>> oncallback, params string[] header)
  280. {
  281. UnityWebRequest webrequest = UnityWebRequest.Post(url, form);
  282. webrequest.timeout = OutTime;
  283. Instance.SetHeader(header, webrequest);
  284. yield return webrequest.SendWebRequest();
  285. ParseRequest(oncallback, webrequest);
  286. }
  287. #endregion
  288. #endregion
  289. #region -- Parse --
  290. ///<summary>解析请求</summary>
  291. ///<param name="oncallback">回调</param>
  292. ///<param name="webrequest">请求代理</param>
  293. private static void ParseRequest<T>(UnityAction<ResponseOutput<T>> oncallback, UnityWebRequest webrequest)
  294. {
  295. ResponseOutput<T> output = new ResponseOutput<T>();
  296. if (!string.IsNullOrEmpty(webrequest.error))
  297. {
  298. #if UNITY_EDITOR||DEBUG_MODEL
  299. Log.LogError($"HTTP请求错误!地址:{webrequest.uri} 消息:{webrequest.error} Code:{webrequest.responseCode}");
  300. #endif
  301. oncallback.Invoke(output.NetworkError(webrequest.error, (int)webrequest.responseCode));
  302. }
  303. else
  304. {
  305. #if UNITY_EDITOR||DEBUG_MODEL
  306. Log.LogDebug(webrequest.uri + " " + webrequest.downloadHandler.text, WSLogType.绿);
  307. #endif
  308. output = JsonMapper.ToObject<ResponseOutput<T>>(webrequest.downloadHandler.text);
  309. oncallback.Invoke(output);
  310. }
  311. webrequest.Dispose();
  312. }
  313. ///<summary>解析请求</summary>
  314. ///<param name="webrequest">请求代理</param>
  315. private static ResponseOutput<T> ParseRequest<T>(RequestAsync request)
  316. {
  317. ResponseOutput<T> output = new ResponseOutput<T>();
  318. if (!string.IsNullOrEmpty(request.Request.error))
  319. {
  320. #if UNITY_EDITOR||DEBUG_MODEL
  321. Log.LogError($"HTTP请求错误!地址:{request.Request.uri} 消息:{request.Request.error} Code:{request.Request.responseCode}");
  322. #endif
  323. output.NetworkError(request.Request.error, (int)request.Request.responseCode);
  324. }
  325. else
  326. {
  327. #if UNITY_EDITOR||DEBUG_MODEL
  328. Log.LogDebug(request.Request.uri + " " + request.Request.downloadHandler.text, WSLogType.绿);
  329. #endif
  330. output = JsonMapper.ToObject<ResponseOutput<T>>(request.Request.downloadHandler.text);
  331. }
  332. request.Dispose();
  333. return output;
  334. }
  335. /// <summary>排除错误码</summary>
  336. /// <param name="output">请求数据</param>
  337. /// <param name="method">方法</param>
  338. /// <param name="butname">请求错误后提示模板可以开启第二个按钮(按钮名称)</param>
  339. /// <param name="oncallback">按钮回调</param>
  340. public static bool ParseErrorCode(IResponseOutput output, UnityAction method, string butname = "", UnityAction oncallback = null)
  341. {
  342. if (ErrorCode.ContainsKey(output.code))
  343. {
  344. string msg = ErrorCode[output.code];
  345. MessagerContorller.OpenMessageView(MessagerType.Error, msg, "重试", () => { method.Invoke(); }, butname, oncallback);
  346. return true;
  347. }
  348. return false;
  349. }
  350. #endregion
  351. public override void Dispose()
  352. {
  353. base.Dispose();
  354. Headers.Clear();
  355. DefaultHeaders.Clear();
  356. ErrorCode.Clear();
  357. }
  358. }
  359. }