HttpManager,统一对外接口,目前封装了Get/Put/Post,尚未用的Delete(原理一样)
using System.Collections.Generic;
using System;
using System.Text;
//GET请求会向服务器发送索取数据的请求,从而获取信息。只是用来查询数据,不会修改、增加数据,无论进行多少次操作结果一样。
//PUT请求是向服务器发送数据的,从而改变信息。用来修改数据的内容,但不会增加数据的种类,无论进行多少次操作结果一样。
//POST请求同PUT请求类似,向服务器发送数据。但是会改变数据的种类等资源,会创建新的内容。
//DELETE请求删除某一个资源,尚未使用。
public enum HttpType
Post,
public class HttpManager : MonoSingleton<HttpManager>
private HttpClient httpClient;
private void Awake()
httpClient = new HttpClient();
httpClient.Init();
private void Update()
httpClient.UpdateHttpRequest();
private void OnDestroy()
httpClient.Clear();
/// <summary>
/// Get接口
/// </summary>
/// <typeparam name="T">返回的数据类型</typeparam>
/// <param name="httpId"></param>
/// <param name="getParameDic"></param>
public void HttpGet<T>(int httpId,Dictionary<string,string> getParameDic) where T : class
string getParameStr;
if(getParameDic == null || getParameDic.Count == 0)
getParameStr = null;
StringBuilder stringBuilder = new StringBuilder();
bool isFirst = true;
foreach(var item in getParameDic)
if(isFirst)
isFirst = false;
stringBuilder.Append('&');
stringBuilder.Append(item.Key);
stringBuilder.Append('=');
stringBuilder.Append(item.Value);
getParameStr = stringBuilder.ToString();
httpClient.SendHttpRequest<T>(httpId,HttpType.Get,getParameStr);
/// <summary>
/// Get接口
/// </summary>
/// <typeparam name="T">返回的数据类型</typeparam>
/// <param name="httpId"></param>
/// <param name="getParameStr"></param>
public void HttpGet<T>(int httpId,string getParameStr) where T : class
//Get请求通过URL传递数据的格式:URL中请求的文件名后跟着“ ?”;多组键值对,键值对之间用“&”进行分割;URL中包含汉字、特殊符号、需要对这些字符进行编码。
//url?parame1Name=parame1Value¶me2Name=parame2Value
httpClient.SendHttpRequest<T>(httpId,HttpType.Get,getParameStr);
/// <summary>
/// Get接口
/// </summary>
/// <typeparam name="T">返回的数据类型</typeparam>
/// <param name="httpId"></param>
public void HttpGet<T>(int httpId) where T : class
httpClient.SendHttpRequest<T>(httpId,HttpType.Get,null);
/// <summary>
/// Post接口
/// </summary>
/// <typeparam name="T">返回的数据类型</typeparam>
/// <param name="httpId"></param>
/// <param name="postParameStr"></param>
public void HttpPost<T>(int httpId,string postParameStr) where T : class
httpClient.SendHttpRequest<T>(httpId,HttpType.Post,postParameStr);
/// <summary>
/// Post接口
/// </summary>
/// <typeparam name="T">返回的数据类型</typeparam>
/// <param name="httpId"></param>
/// <param name="postParame"></param>
public void HttpPost<T>(int httpId,object postParame) where T : class
//在传参中定义json
string postParameStr = FileUtility.DataToJson(postParame);
//UnityEngine.Debug.Log(postParameStr);
httpClient.SendHttpRequest<T>(httpId,HttpType.Post,postParameStr);
/// <summary>
/// Put接口
/// </summary>
/// <param name="httpId"></param>
/// <param name="putParameStr"></param>
public void HttpPut(int httpId,string putParameStr)
httpClient.SendHttpRequest<string>(httpId,HttpType.Put,putParameStr);
/// <summary>
/// Put接口
/// </summary>
/// <param name="httpId"></param>
/// <param name="putParame"></param>
public void HttpPut(int httpId,object putParame)
string putParameStr = FileUtility.DataToJson(putParame);
httpClient.SendHttpRequest<string>(httpId,HttpType.Put,putParameStr);
HttpClient,实际Http请求处理,没有使用协程等待UnityWebRequest响应,避免了频繁的创建启动协程,
在sendList中记录需要发送的请求,在receiveList中记录已发送,需要等待返回的请求,通过webRequest.isDone判断是否已得到服务器响应
using System.Collections.Generic;
using System;
using UnityEngine.Networking;
using UnityEngine;
using System.Text;
public class HttpClient
private const int webReqTimeout = 15;
private const int webReqTryCount = 3;
//发送/接受队列
private List<HttpPack> sendList = new List<HttpPack>(10);
private List<HttpPack> receiveList = new List<HttpPack>(10);
#region --- 外部接口 ---
public void Init()
public void Clear()
public void UpdateHttpRequest()
HandleSend();
HandleRecive();
/// <summary>
/// 发送服务器请求
/// </summary>
/// <typeparam name="T">返回值类型</typeparam>
/// <param name="httpId"></param>
/// <param name="httpType"></param>
/// <param name="parame"></param>
public void SendHttpRequest<T>(int httpId,HttpType httpType,string parame) where T : class
AddHttpRequest<T>(httpId,httpType,parame,typeof(T));
#endregion
//注册一个请求到发送队列中
private void AddHttpRequest<T>(int httpId,HttpType httpType,string parame,Type dataType) where T : class
//将参数设置到HttpPack中然后插入到发送队列里
//HttpPack pack = GetHttpPack();
HttpPack<T> pack = new HttpPack<T>();
pack.id = httpId;
string apiKey = HttpId.GetHttpApi(httpId);
if(string.IsNullOrEmpty(apiKey))
Debug.LogError("为获取到对应的Api : " + httpId);
return;
string serviceHost = "******";
pack.url = serviceHost + apiKey;
pack.httpType = httpType;
pack.dataType = dataType;
pack.parame = parame;
pack.tryCount = webReqTryCount;
sendList.Add(pack);
//从发送队列中取得一个HttpPack分类型调用请求
private void HandleSend()
if(sendList.Count == 0)
return;
for(int i = 0; i < sendList.Count; i++)
HttpPack pack = sendList[i];
switch(pack.httpType)
case HttpType.Get:
//Get请求
if(!string.IsNullOrEmpty(pack.parame))
//在Url后拼接参数字符串
pack.url = string.Format("{0}?{1}",pack.url,pack.parame);
pack.webRequest = new UnityWebRequest(pack.url,UnityWebRequest.kHttpVerbGET);
pack.webRequest.downloadHandler = new DownloadHandlerBuffer();
pack.webRequest.timeout = webReqTimeout;
pack.webRequest.SetRequestHeader("Content-Type","text/json;charset=utf-8");
pack.webRequest.SendWebRequest();
break;
case HttpType.Post:
//Post请求
pack.webRequest = new UnityWebRequest(pack.url,UnityWebRequest.kHttpVerbPOST);
if(!string.IsNullOrEmpty(pack.parame))
byte[] databyte = Encoding.UTF8.GetBytes(pack.parame);
pack.webRequest.uploadHandler = new UploadHandlerRaw(databyte);
pack.webRequest.downloadHandler = new DownloadHandlerBuffer();
pack.webRequest.timeout = webReqTimeout;
pack.webRequest.SetRequestHeader("Content-Type","text/json;charset=utf-8");
pack.webRequest.SendWebRequest();
break;
case HttpType.Put:
//Put
pack.webRequest = new UnityWebRequest(pack.url,UnityWebRequest.kHttpVerbPUT);
if(!string.IsNullOrEmpty(pack.parame))
byte[] databyte = Encoding.UTF8.GetBytes(pack.parame);
pack.webRequest.uploadHandler = new UploadHandlerRaw(databyte);
pack.webRequest.downloadHandler = new DownloadHandlerBuffer();
pack.webRequest.timeout = webReqTimeout;
pack.webRequest.SetRequestHeader("Content-Type","text/json;charset=utf-8");
pack.webRequest.SendWebRequest();
break;
receiveList.Add(pack);
sendList.Clear();
//处理接收
private void HandleRecive()
if(receiveList.Count == 0)
return;
for(int i = receiveList.Count - 1; i >= 0; i--)
HttpPack pack = receiveList[i];
if(pack.webRequest == null)
receiveList.Remove(pack);
continue;
if(pack.webRequest.isDone)
else if(pack.webRequest.isHttpError || pack.webRequest.isNetworkError)
Debug.LogError(pack.webRequest.error);
continue;
int responseCode = (int)pack.webRequest.responseCode;
string responseJson = pack.webRequest.downloadHandler.text;
pack.webRequest.Abort();
pack.webRequest.Dispose();
pack.webRequest = null;
receiveList.Remove(pack);
if(responseCode != 200 && --pack.tryCount > 0)
Debug.Log("try " + pack.tryCount);
sendList.Add(pack);
continue;
CheckResponseCode(pack.id,responseCode,responseJson);
pack.OnData(responseJson,responseCode,pack.id);
private void CheckResponseCode(int httpId,int responseCode,string responseJson)
if(responseCode == 200)
return;
int codeType = responseCode / 100;
string apiKey = HttpId.GetHttpApi(httpId);
switch(codeType)
case 4:
Debug.Log(string.Format("{0} : {1} : 客户端错误,请尝试重试操作~",responseCode,apiKey));
break;
case 5:
case 6:
Debug.Log(string.Format("{0} : {1} : 服务器错误,请尝试重新登陆~",responseCode,apiKey));
break;
default:
Debug.Log(string.Format("{0} : {1} : 未知错误,请尝试重试操作~",responseCode,apiKey));
break;
HttpPack,记录每次请求数据,在收到服务器返回数据后,通过泛型将json解析后的数据通过广播系统转发给功能模块
using System;
using UnityEngine;
using UnityEngine.Networking;
public abstract class HttpPack
// 事件id
public int id;
// 请求地址
public string url;
// 协议类型(Get/Post)
public HttpType httpType;
// 返回数据类型
public Type dataType;
// 请求参数
public string parame;
// 重试次数
public int tryCount;
public UnityWebRequest webRequest;
public abstract void OnData(string dataStr,int code,int messageId);
public class HttpPack<T> : HttpPack where T : class
public override void OnData(string dataStr,int code,int messageId)
T data;
//返回数据只有两种格式:字符串或类
if(typeof(T).Name == "String")
data = dataStr as T;
data = FileUtility.JsonToData<T>(dataStr);
//广播系统发出消息,功能模块开始处理服务器返回数据
//MessageBroker.Instance.Publish<T>(data,messageId);
HttpId,使用id作为key,既用于Http发送请求(通过自定义特性,可以将id与api绑定,每次发送请求只需要传入id,自动拼接url),又用于广播系统广播消息
public class HttpId
//示例,给id标记api
[HttpApiKey("Register")]
public const int registerId = 10001;
[HttpApiKey("Login")]
public const int loginId = 10002;
static HttpId()
System.Reflection.FieldInfo[] fields = typeof(HttpId).GetFields();
Type attType = typeof(HttpApiKey);
for(int i = 0; i < fields.Length; i++)
if(fields[i].IsDefined(attType,false))
int id = (int)fields[i].GetValue(null);
object attribute = fields[i].GetCustomAttributes(attType,false)[0];
string api = (attribute as HttpApiKey).httpApi;
idDic[id] = api;
private static Dictionary<int,string> idDic = new Dictionary<int,string>();
public static string GetHttpApi(int httpId)
idDic.TryGetValue(httpId,out var api);
return api;
public class HttpApiKey : Attribute
public HttpApiKey(string _httpApi)
httpApi = _httpApi;
public string httpApi;
HttpManager,统一对外接口using System.Collections.Generic;using System;using System.Text;//GET请求会向服务器发送索取数据的请求,从而获取信息。只是用来查询数据,不会修改、增加数据,无论进行多少次操作结果一样。//PUT请求是向服务器发送数据的,从而改变信息。用来修改数据的内容,但不会增加数据的种类,无论进行多少次操作结果一样。//POST请求同PUT请求类似,向服务器发送数据。但是会改变数据的种类等资源,会创.
Unity 中通过UnityWebRequest 以GET形式传authorization 的参数请求数据。
注意: 以Header头文件的形式发送请求,authorization要放入请求头部。
以头文件形式发起请求进行Token验证,token为Authorization中的授权验证码。
场景:公司最近项目需要对接http的后台服务器后发送请求并处理其返回结果,在使用WWW时发现新版本已经对该API弃用,于是使用unity新版的api:UnityWebRequest进行发送http协议的请求。
遇到的问题:在使用UnityWebRequest.POST进行请求时,HTTP服务器那边总是会返回HTTP/1.1 500 Internal Server Error的错误,后来跟后台沟通后发现UnityWebRequest.POST使用的默认的请求头(也就是Content_Type)不对导致的。于
Unity 中通过HttpWebRequest以POST形式传JSON格式(键值对格式)的参数请求数据。
注意:处理HttpWebRequest访问https有安全证书的问题( 请求被中止: 未能创建 SSL/TLS 安全通道。)
只需加上以下两行代码就行了。
ServicePointManager.ServerCertificateValidationCallback += ...
Dictionary<string, int> hash = new Dictionary<string, int>();
hash.Add("currentPage", 1);
hash.Add("pageSize", 10);
string str = LitJson.JsonMapper.ToJson(hash);
print(str);
string url = "http://192.168.0.103:8084/api/model/selectAll";
UnityWeb
上篇文章介绍了Http请求的接口封装,本篇具体介绍基于HttpWebRequest接口实现的资源请求下载。HttpWebRequestHelper实现完全重新请求下载和断点续传,并且是异步多线程执行的。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.IO;
using System.Text;
using System;
using
【Unity iOS打包上传后台】ITMS-90427: Invalid Swift Support - The expected dylibs are missing from the ***
2301_82243814:
【Unity iOS打包】Undefined symbols: _OBJC_CLASS_$_GULUserDefaults, referenced from: ***
普通网友:
【Unity iOS打包上传后台】ITMS-90427: Invalid Swift Support - The expected dylibs are missing from the ***
普通网友:
【Unity iOS打包上传后台】ITMS-90427: Invalid Swift Support - The expected dylibs are missing from the ***
【Unity iOS打包】Undefined symbols: _OBJC_CLASS_$_GULUserDefaults, referenced from: ***
【Unity iOS打包】The bundle at ‘***.app/Frameworks/UnityFramework.framework‘ contains disallowed file ··