Files
tianrunCRM/Assets/CoolapeFrame/Scripts/toolkit/WWWEx.cs
2020-07-04 14:41:25 +08:00

741 lines
30 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
********************************************************************************
*Copyright(C),coolae.net
*Author: chenbin
*Version: 2.0
*Date: 2017-01-09
*Description: WWW包装
*Others:
*History:
*********************************************************************************
*/
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Collections.Generic;
namespace Coolape
{
public enum CLAssetType
{
text,
bytes,
texture,
assetBundle,
audioClip,
}
public class WWWEx : MonoBehaviour
{
public static WWWEx self;
public static Hashtable wwwMapUrl = new Hashtable();
public static Hashtable wwwMap4Check = new Hashtable();
public static Hashtable wwwMap4Get = new Hashtable();
public int checkTimeOutSec = 5;
public delegate void RedCallback(string url);
public bool isCheckWWWTimeOut = false;
public bool isPrintUrl = false;
float lastCheckTimeOutTime = 0;
public WWWEx()
{
self = this;
}
private void Update()
{
if (!isCheckWWWTimeOut) return;
if (Time.realtimeSinceStartup - lastCheckTimeOutTime > 0)
{
lastCheckTimeOutTime = Time.realtimeSinceStartup + 3;
checkWWWTimeout();
}
if (wwwMap4Check.Count <= 0)
{
isCheckWWWTimeOut = false;
}
if (wwwMapUrl.Count <= 0)
{
enabled = false;
}
}
IEnumerator exeWWW(UnityWebRequest www, string url, CLAssetType type,
object successCallback,
object failedCallback, object orgs,
bool isCheckTimeout,
int maxFailTimes, int failedTimes,
RedCallback redrectioncallback = null)
{
if (isPrintUrl && url.StartsWith("http://"))
{
Debug.LogError(url);
}
wwwMapUrl[url] = www;
if (isCheckTimeout)
{
addCheckWWWTimeout(www, url, checkTimeOutSec, failedCallback, orgs, maxFailTimes, failedTimes, redrectioncallback);
}
using (www)
{
yield return www.SendWebRequest();
try
{
uncheckWWWTimeout(www, url);
if (www.isNetworkError || www.isHttpError)
{
long retCode = www.responseCode;
Debug.LogError(www.error + ",retCode==" + retCode + "," + url);
if (retCode == 300 || retCode == 301 || retCode == 302)
{
// 重定向处理
string url2 = www.GetResponseHeader("Location");
if (string.IsNullOrEmpty(url2))
{
Utl.doCallback(failedCallback, null, orgs);
}
else
{
if (redrectioncallback != null)
{
redrectioncallback(url2);
}
}
}
else
{
if (maxFailTimes > failedTimes + 1)
{
redrectioncallback(url);
}
else
{
Utl.doCallback(failedCallback, null, orgs);
}
}
}
else
{
object content = null;
switch (type)
{
case CLAssetType.text:
content = www.downloadHandler.text;
break;
case CLAssetType.bytes:
content = www.downloadHandler.data;
break;
case CLAssetType.texture:
content = DownloadHandlerTexture.GetContent(www);
break;
case CLAssetType.assetBundle:
content = DownloadHandlerAssetBundle.GetContent(www);
break;
case CLAssetType.audioClip:
content = DownloadHandlerAudioClip.GetContent(www);
break;
}
Utl.doCallback(successCallback, content, orgs, www);
}
}
catch (System.Exception e)
{
Debug.LogError(e);
if (maxFailTimes > failedTimes + 1)
{
redrectioncallback(url);
}
else
{
Utl.doCallback(failedCallback, null, orgs);
}
}
}
wwwMap4Get.Remove(url);
wwwMapUrl.Remove(url);
if (www != null)
{
www.Dispose();
www = null;
}
}
public static void setWWWHeader(UnityWebRequest www, object header)
{
if (header != null)
{
if (header is XLua.LuaTable)
{
((XLua.LuaTable)header).ForEach<string, object>((key, val) =>
{
www.SetRequestHeader(key, val.ToString());
});
}
else if (header is Hashtable)
{
Hashtable m = ((Hashtable)header);
foreach (var k in m.Keys)
{
www.SetRequestHeader(k.ToString(), m[k].ToString());
}
}
}
}
/// <summary>
/// Get the specified url, type, successCallback, failedCallback, orgs and isCheckTimeout.
/// </summary>
/// <returns>The get.</returns>
/// <param name="url">URL.</param>
/// <param name="type">Type.</param>
/// <param name="successCallback">Success callback.</param>
/// <param name="failedCallback">Failed callback.</param>
/// <param name="orgs">Orgs.回调参数</param>
/// <param name="isCheckTimeout">If set to <c>true</c> is check timeout. 检测超时</param>
public static UnityWebRequest get(string url, CLAssetType type,
object successCallback,
object failedCallback, object orgs,
bool isCheckTimeout = true, int maxFailTimes = 1)
{
return _get(url, null, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, 0);
}
public static UnityWebRequest get(string url, object header, CLAssetType type,
object successCallback,
object failedCallback, object orgs,
bool isCheckTimeout = true, int maxFailTimes = 1)
{
return _get(url, header, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, 0);
}
public static UnityWebRequest getWithHeader(string url, object header, CLAssetType type,
object successCallback,
object failedCallback, object orgs,
bool isCheckTimeout = true, int maxFailTimes = 1)
{
return _get(url, header, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, 0);
}
private static UnityWebRequest _get(string url, object header, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout,
int maxFailTimes, int failedTimes
)
{
try
{
if (string.IsNullOrEmpty(url))
return null;
self.enabled = true;
UnityWebRequest www = null;
switch (type)
{
case CLAssetType.texture:
www = UnityWebRequestTexture.GetTexture(url);
break;
case CLAssetType.assetBundle:
www = UnityWebRequestAssetBundle.GetAssetBundle(url);
break;
default:
www = UnityWebRequest.Get(url);
break;
}
setWWWHeader(www, header);
Coroutine cor = self.StartCoroutine(self.exeWWW(www, url, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes, (url2) =>
{
_get(url2, header, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes + 1);
}));
wwwMap4Get[url] = cor;
return www;
}
catch (System.Exception e)
{
Debug.LogError(e);
Utl.doCallback(failedCallback, null, orgs);
return null;
}
}
public static UnityWebRequest post(string url, object header, string jsonMap, CLAssetType type,
object successCallback,
object failedCallback, object orgs,
bool isCheckTimeout = true, int maxFailTimes = 1)
{
Hashtable map = JSON.DecodeMap(jsonMap);
return post(url, header, map, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes);
}
public static UnityWebRequest post(string url, object header, Hashtable map, CLAssetType type,
object successCallback,
object failedCallback, object orgs,
bool isCheckTimeout = true, int maxFailTimes = 1)
{
try
{
self.enabled = true;
WWWForm data = new WWWForm();
if (map != null)
{
foreach (DictionaryEntry cell in map)
{
if (cell.Value is int)
{
data.AddField(cell.Key.ToString(), int.Parse(cell.Value.ToString()));
}
else if (cell.Value is byte[])
{
data.AddBinaryData(cell.Key.ToString(), (byte[])(cell.Value));
}
else
{
data.AddField(cell.Key.ToString(), cell.Value.ToString());
}
}
}
return post(url, header, data, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes);
}
catch (System.Exception e)
{
Debug.LogError(e);
Utl.doCallback(failedCallback, null, orgs);
return null;
}
}
public static UnityWebRequest post(string url, object header, WWWForm data, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout = true,
int maxFailTimes = 1)
{
return _post(url, header, data, type,
successCallback,
failedCallback, orgs, isCheckTimeout,
maxFailTimes, 0);
}
private static UnityWebRequest _post(string url, object header, WWWForm data, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout,
int maxFailTimes, int failedTimes)
{
try
{
if (string.IsNullOrEmpty(url))
return null;
self.enabled = true;
UnityWebRequest www = UnityWebRequest.Post(url, data);
setWWWHeader(www, header);
Coroutine cor = self.StartCoroutine(
self.exeWWW(www, url, type, successCallback, failedCallback, orgs,
isCheckTimeout, maxFailTimes, failedTimes,
(url2) =>
{
_post(url2, header, data, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes + 1);
}));
wwwMap4Get[url] = cor;
return www;
}
catch (System.Exception e)
{
Debug.LogError(e);
Utl.doCallback(failedCallback, null, orgs);
return null;
}
}
public static UnityWebRequest postString(string url, object header, string strData, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout = true,
int maxFailTimes = 1)
{
return _postString(url, header, strData, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, 0);
}
private static UnityWebRequest _postString(string url, object header, string strData, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout, int maxFailTimes, int failedTimes)
{
try
{
if (string.IsNullOrEmpty(url))
return null;
self.enabled = true;
UnityWebRequest www = UnityWebRequest.Post(url, strData);
setWWWHeader(www, header);
Coroutine cor = self.StartCoroutine(
self.exeWWW(www, url, type, successCallback,
failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes,
(url2) =>
{
_postString(url2, header, strData, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes + 1);
}));
wwwMap4Get[url] = cor;
return www;
}
catch (System.Exception e)
{
Debug.LogError(e);
Utl.doCallback(failedCallback, null, orgs);
return null;
}
}
// 因为lua里没有bytes类型所以不能重载所以只能通方法名来
public static UnityWebRequest postBytes(string url, object header, byte[] bytes, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout = true,
int maxFailTimes = 1)
{
return _postBytes(url, header, bytes, type,
successCallback,
failedCallback, orgs, isCheckTimeout,
maxFailTimes, 0);
}
private static UnityWebRequest _postBytes(string url, object header, byte[] bytes, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout,
int maxFailTimes, int failedTimes)
{
try
{
self.enabled = true;
UnityWebRequest www = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
setWWWHeader(www, header);
UploadHandlerRaw MyUploadHandler = new UploadHandlerRaw(bytes);
DownloadHandlerBuffer downloadHandler = new DownloadHandlerBuffer();
//MyUploadHandler.contentType = "application/x-www-form-urlencoded"; // might work with 'multipart/form-data'
www.uploadHandler = MyUploadHandler;
www.downloadHandler = downloadHandler;
Coroutine cor = self.StartCoroutine(
self.exeWWW(www, url, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes,
(url2) =>
{
_postBytes(url2, header, bytes, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes + 1);
}));
wwwMap4Get[url] = cor;
return www;
}
catch (System.Exception e)
{
Debug.LogError(e);
Utl.doCallback(failedCallback, null, orgs);
return null;
}
}
public static UnityWebRequest put(string url, string data, CLAssetType type,
object successCallback,
object failedCallback, object orgs,
bool isCheckTimeout = true, int maxFailTimes = 1)
{
return _put(url, data, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, 0);
}
private static UnityWebRequest _put(string url, string data, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout,
int maxFailTimes, int failedTimes)
{
try
{
if (string.IsNullOrEmpty(url))
return null;
self.enabled = true;
UnityWebRequest www = UnityWebRequest.Put(url, data);
Coroutine cor = self.StartCoroutine(
self.exeWWW(www, url, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes,
(url2) =>
{
_put(url2, data, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes + 1);
}));
wwwMap4Get[url] = cor;
return www;
}
catch (System.Exception e)
{
Debug.LogError(e);
Utl.doCallback(failedCallback, null, orgs);
return null;
}
}
public static UnityWebRequest put(string url, byte[] data, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout = true, int maxFailTimes = 1)
{
return _put(url, data, type,
successCallback,
failedCallback, orgs, isCheckTimeout,
maxFailTimes, 0);
}
private static UnityWebRequest _put(string url, byte[] data, CLAssetType type,
object successCallback,
object failedCallback, object orgs, bool isCheckTimeout,
int maxFailTimes, int failedTimes)
{
try
{
if (string.IsNullOrEmpty(url))
return null;
self.enabled = true;
UnityWebRequest www = UnityWebRequest.Put(url, data);
Coroutine cor = self.StartCoroutine(
self.exeWWW(www, url, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes,
(url2) =>
{
_put(url2, data, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes + 1);
}));
wwwMap4Get[url] = cor;
return www;
}
catch (System.Exception e)
{
Debug.LogError(e);
Utl.doCallback(failedCallback, null, orgs);
return null;
}
}
/// <summary>
/// Uploads the file.上传文件
/// </summary>
/// <returns>The file.</returns>
/// <param name="url">URL.</param>
/// <param name="sectionName">Section name. 对应java里的new FilePart("sectionName", f) </param>
/// <param name="fileName">File name.</param>
/// <param name="fileContent">File content.</param>
/// <param name="type">Type.</param>
/// <param name="successCallback">Success callback.</param>
/// <param name="failedCallback">Failed callback.</param>
/// <param name="orgs">Orgs.</param>
/// <param name="isCheckTimeout">If set to <c>true</c> is check timeout.</param>
public static UnityWebRequest uploadFile(string url, string sectionName, string fileName, byte[] fileContent, CLAssetType type,
object successCallback, object failedCallback, object orgs, bool isCheckTimeout = true, int maxFailTimes = 1)
{
return _uploadFile(url, sectionName, fileName, fileContent, type,
successCallback, failedCallback, orgs, isCheckTimeout,
maxFailTimes, 0);
}
private static UnityWebRequest _uploadFile(string url, string sectionName, string fileName, byte[] fileContent, CLAssetType type,
object successCallback, object failedCallback, object orgs, bool isCheckTimeout,
int maxFailTimes, int failedTimes)
{
try
{
if (string.IsNullOrEmpty(url))
return null;
self.enabled = true;
MultipartFormFileSection fileSection = new MultipartFormFileSection(sectionName, fileContent, fileName, "Content-Type: multipart/form-data;");
List<IMultipartFormSection> multForom = new List<IMultipartFormSection>();
multForom.Add(fileSection);
UnityWebRequest www = UnityWebRequest.Post(url, multForom);
Coroutine cor = self.StartCoroutine(
self.exeWWW(www, url, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes,
(url2) =>
{
_uploadFile(url2, sectionName, fileName, fileContent, type, successCallback, failedCallback, orgs, isCheckTimeout, maxFailTimes, failedTimes + 1);
}));
wwwMap4Get[url] = cor;
return www;
}
catch (System.Exception e)
{
Debug.LogError(e);
Utl.doCallback(failedCallback, null, orgs);
return null;
}
}
/// <summary>
/// Checks the WWW timeout.
/// </summary>
/// <param name="www">Www.</param>
/// <param name="checkProgressSec">Check progress sec.</param>
/// <param name="timeoutCallback">Timeout callback.</param>
public static void addCheckWWWTimeout(UnityWebRequest www, string url,
float checkProgressSec, object timeoutCallback, object orgs,
int maxFailTimes, int failedTimes, RedCallback redrectioncallback)
{
if (www == null || www.isDone)
return;
self.enabled = true;
self.isCheckWWWTimeOut = true;
checkProgressSec = checkProgressSec <= 0 ? 5 : checkProgressSec;
//UnityEngine.Coroutine cor = self.StartCoroutine(doCheckWWWTimeout(www, url, checkProgressSec, timeoutCallback, 0, orgs));
NewList list = ObjPool.listPool.borrowObject();
list.Add(url);
list.Add(timeoutCallback);
list.Add(checkProgressSec);
list.Add(orgs);
list.Add(0f);
list.Add(0f);
list.Add(Time.realtimeSinceStartup + checkProgressSec);
list.Add(maxFailTimes);
list.Add(failedTimes);
list.Add(redrectioncallback);
wwwMap4Check[www] = list;//DateEx.nowMS + checkProgressSec*1000;
}
public static void checkWWWTimeout()
{
NewList keys = ObjPool.listPool.borrowObject();
keys.AddRange(wwwMap4Check.Keys);
UnityWebRequest www = null;
NewList list = null;
for (int i = 0; i < keys.Count; i++)
{
www = keys[i] as UnityWebRequest;
if (www != null)
{
list = wwwMap4Check[www] as NewList;
if (list != null)
{
doCheckWWWTimeout(www, list);
}
}
}
keys.Clear();
ObjPool.listPool.returnObject(keys);
keys = null;
}
public static void doCheckWWWTimeout(UnityWebRequest www, NewList list)
{
//yield return new WaitForSeconds(checkProgressSec);
string url = list[0] as string;
object timeoutCallback = list[1];
float checkProgressSec = (float)(list[2]);
object orgs = list[3];
float oldProgress = (float)(list[4]);
float oldSize = (float)(list[5]);
float lastCheckTime = (float)(list[6]);
int maxFailTimes = (int)(list[7]);
int failedTimes = (int)(list[8]);
RedCallback redrectioncallback = list[9] as RedCallback;
if (Time.realtimeSinceStartup - lastCheckTime < 0)
{
return;
}
try
{
if (www != null)
{
if (www.isDone)
{
wwwMap4Check.Remove(www);
list.Clear();
ObjPool.listPool.returnObject(list);
}
else
{
float curProgress = 0;
float curSize = 0;
if (www.method == "PUT")
{
curProgress = www.uploadProgress;
if (www.uploadHandler != null && www.uploadHandler.data != null)
{
curSize = www.uploadHandler.data.Length;
}
}
else
{
curProgress = www.downloadProgress;
if (www.downloadHandler != null && www.downloadHandler.data != null)
{
curSize = www.downloadHandler.data.Length;
}
}
if (Mathf.Abs(curProgress - oldProgress) < 0.0001f
&& Mathf.Abs(curSize - oldSize) < 0.0001f)
{
//说明没有变化,可能网络不给力
if (maxFailTimes > failedTimes + 1)
{
if (redrectioncallback != null)
{
redrectioncallback(url);
}
}
else
{
Coroutine corout = wwwMap4Get[url] as Coroutine;
if (corout != null)
{
self.StopCoroutine(corout);
}
wwwMap4Get.Remove(url);
wwwMapUrl.Remove(url);
list.Clear();
ObjPool.listPool.returnObject(list);
wwwMap4Check.Remove(www);
www.Abort();
www.Dispose();
www = null;
Debug.LogError("www time out! url==" + url);
Utl.doCallback(timeoutCallback, null, orgs);
}
}
else
{
//Coroutine cor = self.StartCoroutine(doCheckWWWTimeout(www, url, checkProgressSec, timeoutCallback, curProgress, orgs));
list[4] = curProgress;
list[5] = curSize;
list[6] = Time.realtimeSinceStartup + checkProgressSec;
wwwMap4Check[www] = list;
}
}
}
}
catch (System.Exception e)
{
Debug.LogError(e);
}
}
public static void uncheckWWWTimeout(UnityWebRequest www, string url)
{
try
{
if (www != null && !ReferenceEquals(www, null))
{
wwwMap4Get.Remove(url);
NewList list = wwwMap4Check[www] as NewList;
if (list != null)
{
list.Clear();
ObjPool.listPool.returnObject(list);
}
wwwMap4Check.Remove(www);
}
}
catch (System.Exception e)
{
Debug.LogError(e);
}
}
public static UnityWebRequest getWwwByUrl(string Url)
{
if (string.IsNullOrEmpty(Url))
return null;
return wwwMapUrl[Url] as UnityWebRequest;
}
static void onWWWFailed()
{
}
}
}