关键词:UnityWebRequest、Http协议、Get请求、0 bytes received
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;public class MyWebRequest : MonoBehaviour
{public class CustomWebRequestObject{public Coroutine coroutine;public UnityWebRequest webRequest;}public class CustomWebRequestGetData{public int id;public string url;}public class CustomWebRequestPostData{public int id;public string url;public Dictionary<string, string> data;}public const int TIME_OUT = 10; //超时时间private static int ID = 0; //唯一ID递增public Action<int, string> OnResponse; //Web成功响应回调private Dictionary<int, CustomWebRequestObject> m_CustomWebRequestObjDict; //缓存协程字典private Queue<CustomWebRequestGetData> m_GetQueue;private Queue<CustomWebRequestPostData> m_PostQueue;private int m_ActivingRequestCnt;public void Awake(){m_CustomWebRequestObjDict = new Dictionary<int, CustomWebRequestObject>();m_GetQueue = new Queue<CustomWebRequestGetData>();m_PostQueue = new Queue<CustomWebRequestPostData>();m_ActivingRequestCnt = 0;}/// <summary>/// 返回登录调用/// </summary>public void OnBack2Login(){if (m_CustomWebRequestObjDict.Count > 0){foreach (var v in m_CustomWebRequestObjDict.Values){v.webRequest?.Abort();StopCoroutine(v.coroutine);}m_CustomWebRequestObjDict.Clear();}m_GetQueue.Clear();m_PostQueue.Clear();m_ActivingRequestCnt = 0;}#region Get/// <summary>/// Get方式请求/// </summary>/// <param name="url"></param>/// <returns></returns>public int Request(string url){ID++;int id = ID;Debug.Log($"[CustomWebRequest] web request [Get] *Enqueue* id:{ID}, url:{url}");m_GetQueue.Enqueue(new CustomWebRequestGetData(){id = id,url = url});InternalGet();return id;}private void InternalGet(){if (m_GetQueue.Count <= 0 || m_ActivingRequestCnt > 0){return;}m_ActivingRequestCnt++;CustomWebRequestGetData customWebRequestData = m_GetQueue.Dequeue();int id = customWebRequestData.id;string url = customWebRequestData.url;Debug.Log($"[CustomWebRequest] web request [Get] id:{ID}, url:{url}");//UnityWebRequest webRequest = UnityWebRequest.Get(url);UnityWebRequest webRequest = new UnityWebRequest(url);DownloadHandlerBuffer Download = new DownloadHandlerBuffer();webRequest.downloadHandler = Download;webRequest.method = UnityWebRequest.kHttpVerbGET;webRequest.chunkedTransfer = false;webRequest.useHttpContinue = false;webRequest.redirectLimit = 0;webRequest.timeout = TIME_OUT;Coroutine coroutine = StartCoroutine(EnumeratorGet(id, webRequest));m_CustomWebRequestObjDict.Add(id, new CustomWebRequestObject(){coroutine = coroutine,webRequest = webRequest});}/// <summary>/// Get方式协程处理/// </summary>/// <param name="id">唯一ID</param>/// <param name="url">URL</param>/// <returns></returns>IEnumerator EnumeratorGet(int id, UnityWebRequest webRequest){yield return webRequest.SendWebRequest();if (webRequest.isHttpError || webRequest.isNetworkError){Debug.LogError(string.Format("[CustomWebRequest] web request [Get] fail, id:{0},isHttpError:{1},isNetworkError:{2},TIME_OUT:{3},error:{4}",id, webRequest.isHttpError, webRequest.isNetworkError, TIME_OUT, webRequest.error));}else{string data = webRequest.downloadHandler.text;Debug.Log("[CustomWebRequest] web request [Get] success, id:" + id + ",data:" + data);OnResponse?.Invoke(id, data);}if (webRequest.isDone){string data = webRequest.downloadHandler != null ? webRequest.downloadHandler.text : "";Debug.LogWarning("[CustomWebRequest] web request [Get] response, id:" + id + ",data:" + data);}if (m_CustomWebRequestObjDict.ContainsKey(id)){m_CustomWebRequestObjDict.Remove(id);}m_ActivingRequestCnt--;TryContinueRequest();}#endregion#region Postpublic int Post(string url, string dataJson){ID++;int id = ID;Debug.Log($"[CustomWebRequest] web request [Post] *Enqueue* id:{ID}, dataJson:{dataJson}");m_PostQueue.Enqueue(new CustomWebRequestPostData(){id = id,url = url,data = JsonConvert.DeserializeObject<Dictionary<string, string>>(dataJson)});InternalPost();return id;}private void InternalPost(){if (m_PostQueue.Count <= 0 || m_ActivingRequestCnt > 0){return;}m_ActivingRequestCnt++;CustomWebRequestPostData customWebRequestPostData = m_PostQueue.Dequeue();int id = customWebRequestPostData.id;string url = customWebRequestPostData.url;Dictionary<string, string> data = customWebRequestPostData.data;Debug.Log($"[CustomWebRequest] web request [Post] id:{ID}, data:{JsonConvert.SerializeObject(data)}");WWWForm form = new WWWForm();foreach (var v in data){form.AddField(v.Key, v.Value);}UnityWebRequest webRequest = UnityWebRequest.Post(url, form);Coroutine coroutine = StartCoroutine(EnumeratorPost(id, webRequest));m_CustomWebRequestObjDict.Add(id, new CustomWebRequestObject(){coroutine = coroutine,webRequest = webRequest});}IEnumerator EnumeratorPost(int id, UnityWebRequest webRequest){yield return webRequest.SendWebRequest();if (webRequest.isHttpError || webRequest.isNetworkError){Debug.LogError(string.Format("[CustomWebRequest] web request [Post] fail, id:{0},isHttpError:{1},isNetworkError:{2},TIME_OUT:{3},error:{4}",id, webRequest.isHttpError, webRequest.isNetworkError, TIME_OUT, webRequest.error));}else{string data = webRequest.downloadHandler.text;Debug.Log("[CustomWebRequest] web request [Post] success, id:" + id + ",data:" + data);OnResponse?.Invoke(id, data);}if (webRequest.isDone){string data = webRequest.downloadHandler != null ? webRequest.downloadHandler.text : "";Debug.LogWarning("[CustomWebRequest] web request [Post] response, id:" + id + ",data:" + data);}if (m_CustomWebRequestObjDict.ContainsKey(id)){m_CustomWebRequestObjDict.Remove(id);}m_ActivingRequestCnt--;TryContinueRequest();}#endregionprivate void TryContinueRequest(){InternalGet();InternalPost();}
}
坑:Get方式请求时,参数不可以过长,过长可能会导致无法正常接收到响应,报错如下:
Curl error 28: 0peration timed out after 10000 milliseconds with 0 bytes received
网上方案(均无法解决)
request.useHttpContinue = false
自定义downloadhandler
System.Net.ServicePointManager.DefaultConnectionLimit=50(默认为2)
最终方案:可更改为Post方式请求解决。