Beispiel #1
0
 public static HttpHost GetHttpHost(string host)
 {
     if (!mHostPool.TryGetValue(host, out HttpHost result))
     {
         result          = new HttpHost(host);
         mHostPool[host] = result;
     }
     return(result);
 }
Beispiel #2
0
        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());
            }
        }
Beispiel #3
0
        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!");
            }
        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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;
            }
        }
Beispiel #6
0
 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;
     }
 }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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();
        }
Beispiel #9
0
            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));
                }
            }
Beispiel #10
0
 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);
 }
Beispiel #11
0
        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));
        }
Beispiel #12
0
        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);
                        }
                    }
                }
            }
        }
Beispiel #13
0
 internal HttpApiClient(string host)
 {
     Host = HttpHost.GetHttpHost(host); //new HttpHost(host);
 }
Beispiel #14
0
 public HttpTester(Uri uri)
 {
     mHttpHost = new BeetleX.Http.Clients.HttpHost(uri);
 }
Beispiel #15
0
 public HttpApiClient(string host)
 {
     Host = new HttpHost(host);
 }
Beispiel #16
0
        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));
        }