通用框架(七)HTTP通信

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了。

留下评论

电子邮件地址不会被公开。 必填项已用*标注