using System; using System.Text; using BestHTTP; using BestHTTP.Forms; namespace Http { public enum RequestState { Success, Aborted, Fail, ConnectionTimedOut, TimedOut } public class ResultInfo { public string Id; public object Tag; public RequestState State; public HTTPResponse Response; } public class SingleHttp { public string Id; public object Tag; public HTTPMethods Type; public float CustomTimeout; private bool _isKeepAlive; private bool _disableCache; private double _timeout; private double _connectTimeout; private bool _isRequesting; private HTTPRequest _request; private HTTPUrlEncodedForm _encodedForm; private Action _callback; public HTTPRequest Request => _request; public SingleHttp() { Id = string.Empty; Tag = null; Type = HTTPMethods.Get; CustomTimeout = 100f; _isKeepAlive = true; _disableCache = true; _timeout = 60d; _connectTimeout = 20d; _isRequesting = false; } private static SingleHttp _create(HTTPMethods type, string url, Action callback) { var http = new SingleHttp {Type = type, _callback = callback}; HttpDebug.Log(url); http._request = new HTTPRequest(new Uri(url), type, http._OnFinished); http.Id = http.GetHashCode().ToString(); return http; } public static SingleHttp Create(HTTPMethods type, string url, Action callback) { return _create(type, url, callback); } public SingleHttp AddHeader(string key, string value) { _request?.AddHeader(key, value); return this; } public SingleHttp AddParameter(string body) { if (_request == null) return this; _request.RawData = Encoding.UTF8.GetBytes(body); return this; } public SingleHttp AddParameter(string key, string value, bool isLastOne = false) { _encodedForm ??= new HTTPUrlEncodedForm(); _encodedForm.AddField(key, value); if (isLastOne) _request?.SetForm(_encodedForm); return this; } /// /// 跟Send在同一帧使用,会返回两次 /// public void ForceAbort() { if (_request == null) return; if (!_isRequesting) return; _request.Abort(); } public SingleHttp SetId(string id) { Id = id; return this; } public SingleHttp AddTag(object value) { Tag = value; return this; } public SingleHttp AddCustomTimeout(float value) { CustomTimeout = value; return this; } /// /// 指的是从客户端发出请求到接收到数据的限制时间。超出即为超时。默认是60s。 /// /// /// public SingleHttp Timeout(double value) { _timeout = value; return this; } /// /// 是指客户端连接服务器的时间。默认是20s。 /// /// /// public SingleHttp ConnectTimeout(double value) { _connectTimeout = value; return this; } /// /// 告诉服务器我们想连接保持开启, 这样连续的Http请求就不必再次打开连接。 /// 如果我们保持默认开启,会省下不少时间。 如果我们确信不会那么频繁的请求,那么可以设为false。 默认值是false. /// /// /// public SingleHttp KeepAlive(bool value) { _isKeepAlive = value; return this; } /// /// 告诉BestHttp系统用或者不用整个缓存机制。 /// 如果这个值是true,那么系统不会去缓存里查找已存储的响应,而且响应也不会被缓存。 默认值是 true. /// /// /// public SingleHttp DisableCache(bool value) { _disableCache = value; return this; } public void Send() { if (_request == null) return; _isRequesting = true; _request.IsKeepAlive = _isKeepAlive; _request.DisableCache = _disableCache; _request.Timeout = TimeSpan.FromSeconds(_timeout); _request.ConnectTimeout = TimeSpan.FromSeconds(_connectTimeout); _request.Send(); } private void _OnFinished(HTTPRequest req, HTTPResponse resp) { // 手动终止,跟sand在同一帧中,会返回两次 if (!_isRequesting) return; _isRequesting = false; var state = RequestState.Fail; switch (req.State) { // 请求顺利完成 // 服务器发送了一个错误 case HTTPRequestStates.Finished: if (resp.IsSuccess) { state = RequestState.Success; HttpDebug.Log($"Server Result:{resp.StatusCode}-{resp.Message}-{resp.DataAsText}"); } else HttpDebug.LogError($"Server sent Error:{resp.StatusCode}-{resp.Message}-{resp.DataAsText}"); break; // 请求已完成,但出现意外错误。 case HTTPRequestStates.Error: if(req.Exception != null) HttpDebug.LogError($"Request.Exception \n {req.Exception.StackTrace}"); else HttpDebug.LogError("Request.Exception: No Exception"); break; // 请求已中止(可以手动终止) case HTTPRequestStates.Aborted: state = RequestState.Aborted; HttpDebug.LogError("Request Aborted!"); break; // 连接到服务器超时 case HTTPRequestStates.ConnectionTimedOut: state = RequestState.ConnectionTimedOut; HttpDebug.LogError("Connection Timed Out!"); break; // 请求没有在给定时间内完成 case HTTPRequestStates.TimedOut: state = RequestState.TimedOut; HttpDebug.LogError("Processing the request Timed Out!"); break; default: HttpDebug.LogError("Unknown error!"); break; } var info = new ResultInfo {Id = Id, Tag = Tag, State = state, Response = resp}; _callback?.Invoke(info); } } }