public static HttpHost GetHttpHost(string host) { if (!mHostPool.TryGetValue(host, out HttpHost result)) { result = new HttpHost(host); mHostPool[host] = result; } return(result); }
protected override object Invoke(MethodInfo targetMethod, object[] args) { ClientActionHanler handler = Cluster.GetHandler((MethodInfo)targetMethod); var rinfo = handler.GetRequestInfo(args); if (handler.NodeAgent == null || handler.NodeAgent.Version != Cluster.Version) { handler.NodeAgent = Cluster.GetAgent(rinfo.Url); } HttpHost host = handler.NodeAgent.Node.GetClient(); if (host == null) { Exception error = new HttpClientException(null, null, $"request {rinfo.Url} no http nodes are available"); if (handler.Async) { //Type gtype = typeof(AnyCompletionSource<>); //Type type = gtype.MakeGenericType(handler.ReturnType); IAnyCompletionSource source = CompletionSourceFactory.Create(handler.ReturnType, Cluster.TimeOut); //(IAnyCompletionSource)Activator.CreateInstance(type); source.Error(error); return(source.GetTask()); } else { throw error; } } if (!handler.Async) { throw new Exception($"{rinfo.Method} method is not supported and the return value must be task!"); } else { var request = rinfo.GetRequest(host); foreach (var item in Header) { request.Header[item.Key] = item.Value; } var task = request.Execute(); IAnyCompletionSource source = CompletionSourceFactory.Create(handler.ReturnType, Cluster.TimeOut); source.Wait <Response>(task, (c, t) => { if (t.Result.Exception != null) { c.Error(t.Result.Exception); } else { c.Success(t.Result.Body); } }); return(source.GetTask()); } }
public HttpClient(string host) { mHost = HttpHost.GetHttpHost(host); Uri uri = new Uri(host); RequestUrl = uri.PathAndQuery; if (string.IsNullOrEmpty(RequestUrl)) { throw new HttpClientException("Request URL invalid!"); } }
internal void RefreshWeightTable() { var status = Status; if (mLastStatus == status) { return; } else { mLastStatus = status; } HttpHost[] table = new HttpHost[TABLE_SIZE]; int sum = 0; mClients.Sort((x, y) => y.Weight.CompareTo(x.Weight)); List <HttpHost> aclients = new List <HttpHost>(); for (int i = 0; i < mClients.Count; i++) { if (mClients[i].Available) { sum += mClients[i].Weight; aclients.Add(mClients[i]); } } int count = 0; for (int i = 0; i < aclients.Count; i++) { int size = (int)((double)aclients[i].Weight / (double)sum * (double)TABLE_SIZE); for (int k = 0; k < size; k++) { table[count] = aclients[i]; count++; if (count >= TABLE_SIZE) { goto END; } } } int index = 0; while (count < TABLE_SIZE) { table[count] = aclients[index % aclients.Count]; index++; count++; } END: Shuffle(table); mHttpHostTable = table; }
private void Shuffle(HttpHost[] list) { Random rng = new Random(); int n = list.Length; while (n > 1) { n--; int k = rng.Next(n + 1); HttpHost value = list[k]; list[k] = list[n]; list[n] = value; } }
private async void OnVerify(HttpHost host) { try { var request = host.Get("/", null, null, null, null); var result = await request.Execute(); } catch { } finally { host.InVerify = false; } }
public IApiNode Add(string host, int weight) { Uri url = new Uri(host); if (mClients.Find(c => c.Host == url.Host && c.Port == url.Port) == null) { var item = HttpHost.GetHttpHost(host);//new HttpHost(host); item.ID = mID << mClients.Count; item.Weight = weight; item.MaxRPS = 0; mClients.Add(item); RefreshWeightTable(); } return(this); }
public void Verify() { int count = 0; for (int i = 0; i < mClients.Count; i++) { HttpHost client = mClients[i]; if (!client.Available && !client.InVerify) { client.InVerify = true; count++; Task.Run(() => OnVerify(client)); } } RefreshWeightTable(); }
public Request GetRequest(HttpHost httpApiClient) { switch (Method) { case Request.POST: return(httpApiClient.Post(Url, Header, QueryString, Data, Formatter, Type)); case Request.PUT: return(httpApiClient.Put(Url, Header, QueryString, Data, Formatter, Type)); case Request.DELETE: return(httpApiClient.Delete(Url, Header, QueryString, Formatter, Type)); default: return(httpApiClient.Get(Url, Header, QueryString, Formatter, Type)); } }
public HttpHost GetClient() { if (Available) { HttpHost[] table = mHttpHostTable; if (table == null || table.Length == 0) { return(null); } int count = 0; long index = System.Threading.Interlocked.Increment(ref mIndex); while (count < TABLE_SIZE) { HttpHost client = table[index % TABLE_SIZE]; if (client.Available) { return(client); } index++; count++; } } return(null); }
private async void OnExecute() { HttpClientHandler client = null; Response response; bool closeClient = false; try { object result = null; requestResult = new TaskCompletionSource <object>(); client = await HttpHost.Pool.Pop(); Client = client.Client; AsyncTcpClient asyncClient = (AsyncTcpClient)client.Client; asyncClient.ClientError = onEventClientError; asyncClient.PacketReceive = OnEventClientPacketCompleted; GetConnection?.Invoke(asyncClient); #if NETCOREAPP2_1 using (CodeTrackFactory.Track(Url, CodeTrackLevel.Function, mRequestTrack?.Activity?.Id, "HTTPClient", "Protocol", "Write")) { asyncClient.Send(this); Status = RequestStatus.SendCompleted; } #else asyncClient.Send(this); Status = RequestStatus.SendCompleted; #endif #if NETCOREAPP2_1 using (CodeTrackFactory.Track(Url, CodeTrackLevel.Function, mRequestTrack?.Activity?.Id, "HTTPClient", "Protocol", "Read")) { var a = requestResult.Task; result = await a; } #else var a = requestResult.Task; result = await a; #endif if (result is Exception error) { response = new Response(); response.Exception = new HttpClientException(this, HttpHost.Uri, error.Message, error); Status = RequestStatus.Error; closeClient = true; } else { response = (Response)result; Status = RequestStatus.Received; } if (response.Exception == null) { int code = int.Parse(response.Code); if (response.Length > 0) { try { if (code >= 200 && code < 300) { response.Body = this.Formater.Deserialization(response, response.Stream, this.BodyType, response.Length); } else { response.Body = response.Stream.ReadString(response.Length); } } finally { response.Stream.ReadFree(response.Length); if (response.Chunked) { response.Stream.Dispose(); } response.Stream = null; } } if (!response.KeepAlive) { client.Client.DisConnect(); } if (code >= 400) { response.Exception = new HttpClientException(this, HttpHost.Uri, $"{Url}({response.Code}) [{response.Body}]"); response.Exception.Code = code; } Status = RequestStatus.Completed; } } catch (Exception e_) { HttpClientException clientException = new HttpClientException(this, HttpHost.Uri, e_.Message, e_); response = new Response { Exception = clientException }; Status = RequestStatus.Error; closeClient = true; } if (response.Exception != null) { HttpHost.AddError(response.Exception.SocketError); } else { HttpHost.AddSuccess(); } Response.Current = response; this.Response = response; if (client != null) { if (client.Client is AsyncTcpClient asclient) { asclient.ClientError = null; asclient.PacketReceive = null; } if (closeClient) { await DisConnect(client.Client); } HttpHost.Pool.Push(client); client = null; } await Task.Run(() => mTaskCompletionSource.Success(response)); }
public ClientActionHanler(MethodInfo method) { MethodInfo = method; Method = "GET"; Name = method.Name; DeclaringType = method.DeclaringType; var host = DeclaringType.GetCustomAttribute <HostAttribute>(false); MethodType = MethodInfo.ReturnType; var mhost = method.GetCustomAttribute <HostAttribute>(false); if (mhost != null) { host = mhost; } if (host != null) { this.Host = HttpHost.GetHttpHost(host.Host);// new HttpHost(host.Host); } Async = false; if (MethodInfo.ReturnType != typeof(void)) { if (MethodInfo.ReturnType.Name == "Task`1" || MethodInfo.ReturnType == typeof(Task)) { Async = true; if (MethodInfo.ReturnType.IsGenericType) { ReturnType = MethodInfo.ReturnType.GetGenericArguments()[0]; } } else { ReturnType = MethodInfo.ReturnType; } } foreach (HeaderAttribute h in DeclaringType.GetCustomAttributes <HeaderAttribute>()) { if (!string.IsNullOrEmpty(h.Name) && !string.IsNullOrEmpty(h.Value)) { mHeaders[h.Name] = h.Value; } } foreach (HeaderAttribute h in method.GetCustomAttributes <HeaderAttribute>()) { if (!string.IsNullOrEmpty(h.Name) && !string.IsNullOrEmpty(h.Value)) { mHeaders[h.Name] = h.Value; } } foreach (QueryAttribute q in DeclaringType.GetCustomAttributes <QueryAttribute>()) { if (!string.IsNullOrEmpty(q.Name) && !string.IsNullOrEmpty(q.Value)) { mQueryString[q.Name] = q.Value; } } foreach (QueryAttribute q in method.GetCustomAttributes <QueryAttribute>()) { if (!string.IsNullOrEmpty(q.Name) && !string.IsNullOrEmpty(q.Value)) { mQueryString[q.Name] = q.Value; } } Formater = method.GetCustomAttribute <FormaterAttribute>(); if (Formater == null) { Formater = DeclaringType.GetCustomAttribute <FormaterAttribute>(); } if (Formater == null) { Formater = new JsonFormater(); } var get = method.GetCustomAttribute <GetAttribute>(); if (get != null) { Method = Request.GET; if (!string.IsNullOrEmpty(get.Route)) { RouteTemplateMatch = new RouteTemplateMatch(get.Route); } } var post = method.GetCustomAttribute <PostAttribute>(); if (post != null) { Method = Request.POST; if (!string.IsNullOrEmpty(post.Route)) { RouteTemplateMatch = new RouteTemplateMatch(post.Route); } } var del = method.GetCustomAttribute <DelAttribute>(); if (del != null) { Method = Request.DELETE; if (!string.IsNullOrEmpty(del.Route)) { RouteTemplateMatch = new RouteTemplateMatch(del.Route); } } var put = method.GetCustomAttribute <PutAttribute>(); if (put != null) { Method = Request.PUT; if (!string.IsNullOrEmpty(put.Route)) { RouteTemplateMatch = new RouteTemplateMatch(put.Route); } } Controller = this.DeclaringType.GetCustomAttribute <ControllerAttribute>(); if (Controller != null) { if (!string.IsNullOrEmpty(Controller.BaseUrl)) { BaseUrl = Controller.BaseUrl; } } if (string.IsNullOrEmpty(BaseUrl)) { BaseUrl = "/"; } if (BaseUrl[0] != '/') { BaseUrl = "/" + BaseUrl; } if (BaseUrl.Substring(BaseUrl.Length - 1, 1) != "/") { BaseUrl += "/"; } int index = 0; foreach (var p in method.GetParameters()) { ClientActionParameter cap = new ClientActionParameter(); cap.Name = p.Name; cap.ParameterType = p.ParameterType; cap.Index = index; index++; HeaderAttribute cHeader = p.GetCustomAttribute <HeaderAttribute>(); if (cHeader != null) { if (!string.IsNullOrEmpty(cHeader.Name)) { cap.Name = cHeader.Name; } mHeaderParameters.Add(cap); } else { QueryAttribute cQuery = p.GetCustomAttribute <QueryAttribute>(); if (cQuery != null) { if (!string.IsNullOrEmpty(cQuery.Name)) { cap.Name = cQuery.Name; } mQueryStringParameters.Add(cap); } else { if (RouteTemplateMatch != null && RouteTemplateMatch.Items.Find(i => i.Name == p.Name) != null) { mRouteParameters.Add(cap); } else { mDataParameters.Add(cap); } } } } }
internal HttpApiClient(string host) { Host = HttpHost.GetHttpHost(host); //new HttpHost(host); }
public HttpTester(Uri uri) { mHttpHost = new BeetleX.Http.Clients.HttpHost(uri); }
public HttpApiClient(string host) { Host = new HttpHost(host); }
private async void OnExecute() { HttpClient client = null; Response response; try { client = HttpHost.Pool.Pop(); client.RequestCommpletionSource = mTaskCompletionSource; Client = client.Client; if (client.Client is AsyncTcpClient) { AsyncTcpClient asyncClient = (AsyncTcpClient)client.Client; GetConnection?.Invoke(asyncClient); var a = asyncClient.ReceiveMessage(); if (!a.IsCompleted) { asyncClient.Send(this); Status = RequestStatus.SendCompleted; } var result = await a; if (result is Exception error) { response = new Response(); response.Exception = new HttpClientException(this, HttpHost.Uri, error.Message, error); Status = RequestStatus.Error; } else { response = (Response)result; Status = RequestStatus.Received; } } else { TcpClient syncClient = (TcpClient)client.Client; syncClient.SendMessage(this); Status = RequestStatus.SendCompleted; response = syncClient.ReceiveMessage <Response>(); Status = RequestStatus.Received; } if (response.Exception == null) { int code = int.Parse(response.Code); if (response.Length > 0) { try { if (code == 200) { response.Body = this.Formater.Deserialization(response, response.Stream, this.BodyType, response.Length); } else { response.Body = response.Stream.ReadString(response.Length); } } finally { response.Stream.ReadFree(response.Length); if (response.Chunked) { response.Stream.Dispose(); } response.Stream = null; } } if (!response.KeepAlive) { client.Client.DisConnect(); } if (code != 200) { response.Exception = new HttpClientException(this, HttpHost.Uri, $"{Url}({response.Code}) [{response.Body}]"); response.Exception.Code = code; } Status = RequestStatus.Completed; } } catch (Exception e_) { HttpClientException clientException = new HttpClientException(this, HttpHost.Uri, e_.Message, e_); response = new Response { Exception = clientException }; Status = RequestStatus.Error; } if (response.Exception != null) { HttpHost.AddError(response.Exception.SocketError); } else { HttpHost.AddSuccess(); } Response.Current = response; this.Response = response; if (client != null) { HttpHost.Pool.Push(client); } Task.Run(() => mTaskCompletionSource.Success(response)); }