http是我们经常使用的网络组件,后台服务器人员定义接口,前端人员按照接口规范进行调用。
这次按照以前的http模块来改

其实http模块大同小异,解决多线程问题,最主要的是要跟自己的业务配合起来,一般来说,规则一般都是后台定的,前端人员按照后台人员的规范写接口就行。
下面附核心代码
/// <summary>
/// Http请求的回调数据
/// </summary>
public class HttpCallbackArgs : EventArgs
{
/// <summary>
/// 是否有错
/// </summary>
public bool HasError;
/// <summary>
/// 返回值
/// </summary>
public string Value;
/// <summary>
/// 字节数据
/// </summary>
public byte[] Data;
}
/// <summary>
/// http发送数据的回调委托
/// </summary>
/// <param name="args"></param>
public delegate void HttpSendDataCallBack(HttpCallbackArgs args);
/// <summary>
/// http访问器
/// </summary>
public class HttpRoutine
{
#region 属性
/// <summary>
/// Http请求回调
/// </summary>
private HttpSendDataCallBack m_CallBack;
/// <summary>
/// Http请求回调数据
/// </summary>
private HttpCallbackArgs m_CallBackArgs;
/// <summary>
/// 是否繁忙
/// </summary>
public bool IsBusy
{
get;
private set;
}
/// <summary>
/// 是否获取data数据
/// </summary>
private bool m_IsGetData = false;
#endregion
public HttpRoutine()
{
m_CallBackArgs = new HttpCallbackArgs();
}
#region SendData 发送web数据
/// <summary>
/// 发送web数据
/// </summary>
/// <param name="url"></param>
/// <param name="callBack"></param>
/// <param name="isPost"></param>
/// <param name="isGetData">是否获取字节数据</param>
/// <param name="dic"></param>
public void SendData(string url,
HttpSendDataCallBack callBack,
bool isPost = false,
bool isGetData = false,
Dictionary<string, object> dic = null)
{
if (IsBusy) return;
IsBusy = true;
m_CallBack = callBack;
m_IsGetData = isGetData;
if (!isPost)
{
GetUrl(url);
}
else
{
//web加密
if (dic != null)
{
//客户端标识符
dic["deviceIdentifier"] = DeviceUtil.DeviceIdentifier;
//设备型号
dic["deviceModel"] = DeviceUtil.DeviceModel;
long t = GameEntry.Data.SysDataManager.CurrServerTime;
//签名
dic["sign"] = EncryptUtil.Md5(string.Format("{0}:{1}", t, DeviceUtil.DeviceIdentifier));
//时间戳
dic["t"] = t;
}
string json = string.Empty;
if (dic != null)
{
json = JsonMapper.ToJson(dic);
if (!m_IsGetData)
{
GameEntry.Log(LogCategory.Proto, "<color=#ffa200>发送消息:</color><color=#FFFB80>" + url + "</color>");
GameEntry.Log(LogCategory.Proto, "<color=#ffdeb3>==>>" + json + "</color>");
}
GameEntry.Pool.EnqueueClassObject(dic);
}
PostUrl(url, json);
}
}
#endregion
#region GetUrl Get请求
/// <summary>
/// Get请求
/// </summary>
/// <param name="url"></param>
private void GetUrl(string url)
{
UnityWebRequest data = UnityWebRequest.Get(url);
GameEntry.Http.StartCoroutine(Request(data));
}
#endregion
#region PostUrl Post请求
/// <summary>
/// Post请求
/// </summary>
/// <param name="url"></param>
/// <param name="json"></param>
private void PostUrl(string url, string json)
{
//定义一个表单
WWWForm form = new WWWForm();
//给表单添加值
form.AddField("", json);
UnityWebRequest data = UnityWebRequest.Post(url, form);
GameEntry.Http.StartCoroutine(Request(data));
}
#endregion
#region Request 请求服务器
/// <summary>
/// 请求服务器
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private IEnumerator Request(UnityWebRequest data)
{
yield return data.SendWebRequest();
IsBusy = false;
if (data.isNetworkError || data.isHttpError)
{
if (m_CallBack != null)
{
m_CallBackArgs.HasError = true;
m_CallBackArgs.Value = data.error;
if (!m_IsGetData)
{
GameEntry.Log(LogCategory.Proto, "<color=#00eaff>接收消息:</color><color=#00ff9c>" + data.url + "</color>");
GameEntry.Log(LogCategory.Proto, "<color=#c5e1dc>==>>" + JsonUtility.ToJson(m_CallBackArgs) + "</color>");
}
m_CallBack(m_CallBackArgs);
}
}
else
{
if (m_CallBack != null)
{
m_CallBackArgs.HasError = false;
m_CallBackArgs.Value = data.downloadHandler.text;
if (!m_IsGetData)
{
GameEntry.Log(LogCategory.Proto, "<color=#00eaff>接收消息:</color><color=#00ff9c>" + data.url + "</color>");
GameEntry.Log(LogCategory.Proto, "<color=#c5e1dc>==>>" + JsonUtility.ToJson(m_CallBackArgs) + "</color>");
}
m_CallBackArgs.Data = data.downloadHandler.data;
m_CallBack(m_CallBackArgs);
}
}
data.Dispose();
data = null;
//Debug.Log("把http访问器回池");
GameEntry.Pool.EnqueueClassObject(this);
}
#endregion
}
可以看流程图,对httpRoutine封装了好几层,就是为了给以后开发定好规范,在添加接口不用改动起来那么大,并且还代码看起来清晰,可读性高。
每次用我们每次都会从池中new一个http访问器,GET请求大同小异,POST请求按照和后台约定的加密方式就行处理就好。
到这里http就ok了。