【问题标题】:Limit Outbound Requests going out of ASP.NET Core Web API限制从 ASP.NET Core Web API 发出的出站请求
【发布时间】:2021-12-23 18:23:48
【问题描述】:

我有一个要求,我需要限制从我的应用程序到 XYZ 外部 API 的出站请求的数量。假设我必须在 1 分钟内从我的 API 向该外部 API 发送最多 3 个请求。

我正在使用 RateLimiter Nuget 包 http://david-desmaisons.github.io/RateLimiter/,下面是我的完整代码,它在第 7 次请求之前工作正常,之后,我遇到了错误

“'InnerHandler' 属性必须为 null。提供给 'HttpMessageHandlerBuilder' 的 'DelegatingHandler' 实例不得重复使用或缓存。 处理程序:'Application.DispatcherExtension+DispatcherDelegatingHandler'

ConfigureServices 方法

var handler = TimeLimiter.GetFromMaxCountByInterval(3, TimeSpan.FromMinutes(1)).AsDelegatingHandler();

services
                    .AddRefitClient<IService>()
                    .ConfigureHttpClient((services, client) =>
                    {
                        var config = services.GetRequiredService<TestServiceSettings>();
                        client.BaseAddress = config.BaseUri;
                        client.DefaultRequestHeaders.Add(
                            "Authorization",
                            "Basic " + Convert.ToBase64String(
                                Encoding.Default.GetBytes($"{config.Login}:{config.Password}")));
                    })
                    .AddHttpMessageHandler(() => handler);

services.AddSingleton(_ => handler);

调度程序扩展

public static class DispatcherExtension
    {
        private sealed class DispatcherDelegatingHandler : DelegatingHandler
        {
            private readonly ComposableAsync.IDispatcher _Dispatcher;

            public DispatcherDelegatingHandler(ComposableAsync.IDispatcher dispatcher)
            {
                _Dispatcher = dispatcher;
            }

            protected override Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
            {
                return _Dispatcher.Enqueue(() =>
                    base.SendAsync(request, cancellationToken), cancellationToken);
            }
        }

        public static DelegatingHandler AsDelegatingHandler(
            this ComposableAsync.IDispatcher dispatcher)
        {
            return new DispatcherDelegatingHandler(dispatcher);
        }
    }

我搜索了所有文章,但没有找到任何解决方案。

【问题讨论】:

    标签: c# .net-core


    【解决方案1】:

    通过在每次由configureHandler 委托调用时返回消息处理程序的新实例来解决此问题。根据this link 中给出的文档,它在那里被提及为

    configureHandler 委托应在每次调用时返回消息处理程序的新实例。

    所以最终的代码是这样的

    ConfigureServices 方法

    var handler = TimeLimiter.GetFromMaxCountByInterval(3, TimeSpan.FromMinutes(1));
    
    services
        .AddRefitClient<IService>()
        .ConfigureHttpClient((services, client) =>
        {
             var config = services.GetRequiredService<TestServiceSettings>();
             client.BaseAddress = config.BaseUri;
             client.DefaultRequestHeaders.Add(
                   "Authorization",
                   "Basic " + Convert.ToBase64String(
                          Encoding.Default.GetBytes($"{config.Login}:{config.Password}")));
         })
         .AddHttpMessageHandler(() => handler.AsDelegateHandler());
    

    【讨论】:

      猜你喜欢
      • 2019-04-09
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      相关资源
      最近更新 更多