个人资料

跳过导航链接首页 > 博客列表 > 博客正文

C#限制http client访问速度

:

要在 .NET 中使用速率限制,请引用 System.Threading.RateLimiting NuGet 包

使用示例

 //HttpClient client = new HttpClient();
 HttpClient client = StaticHttpClient._client;

 client.DefaultRequestHeaders.Accept.Clear();
 string region = host_platform.GetHostFromPlatform(platform);

 var url = $"https://{region}/lol/summoner/v4/summoners/{sid}";

 HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
 request.Headers.Add("X-Riot-Token", UserSearch.api_key);

 var ms = await client.SendAsync(request);
 var json = await ms.Content.ReadAsStringAsync();

 var result = JsonConvert.DeserializeObject<Summoner>(json);
代码
    internal class StaticHttpClient
    {

        static StaticHttpClient() 
        {

            
            var options = new TokenBucketRateLimiterOptions
            {
                TokenLimit = 100,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit = 100,
                ReplenishmentPeriod = TimeSpan.FromSeconds(0.05),///1.2s    //0.05
                TokensPerPeriod = 200,
                AutoReplenishment = true
            };

            // Create an HTTP client with the client-side rate limited handler.
            _client = new HttpClient(new ClientSideRateLimitedHandler(new TokenBucketRateLimiter(options)));
       


        }




        public static HttpClient _client { get; set; }




    }


    internal sealed class ClientSideRateLimitedHandler : DelegatingHandler, IAsyncDisposable
    {

        RateLimiter limiter;
        public ClientSideRateLimitedHandler(RateLimiter _limiter) : base(new HttpClientHandler())
        {
            limiter = _limiter;
        }



        protected override async Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {

            using (RateLimitLease lease = await limiter.AcquireAsync(permitCount: 1, cancellationToken))
            {
                if (lease.IsAcquired)
                {
                    return await base.SendAsync(request, cancellationToken);
                }

                var response = new HttpResponseMessage((System.Net.HttpStatusCode)429);
                if (lease.TryGetMetadata(
                        MetadataName.RetryAfter, out TimeSpan retryAfter))
                {
                    response.Headers.Add(
                        "Retry-After",
                        ((int)retryAfter.TotalSeconds).ToString(
                            NumberFormatInfo.InvariantInfo));
                }

                return response;
            }



        }


        async ValueTask IAsyncDisposable.DisposeAsync()
        {
            await limiter.DisposeAsync().ConfigureAwait(false);

            Dispose(disposing: false);
            GC.SuppressFinalize(this);
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing)
            {
                limiter.Dispose();
            }
        }
    }

参考

https://learn.microsoft.com/zh-cn/dotnet/core/extensions/http-ratelimiter

songshizhao
最初发表2024/10/13 12:48:08 最近更新2024/10/13 12:49:50 284
为此篇作品打分
10