asp.net core 는 IHttpClient Factory 에 동적 이름 설정 을 추가 합 니 다.

예 를 들 어 IHttpClient Factory 동적 으로 cer 인증 서 를 추가 하 는 방법
세 가지 방법 이 있어 요.추천 방법.
  • 방법 1:추천 하 는 방법 은 이렇다
  • 
    services.AddHttpClient("a  ").ConfigurePrimaryHttpMessageHandler(...a    )
    services.AddHttpClient("b  ").ConfigurePrimaryHttpMessageHandler(...b    )
    ServiceProvider.GetService<IHttpClientFactory>().CreateClient("a  ")....
  • 방법 2:
  • 완전히 사용자 정의 하려 면 사용 할 수 있 습 니 다new System.Net.Http.HttpClient(handler)
  • 방법 3:
  • 설정 을 바 꾸 는 방식 도 논리 적 으로 자신의 HttpClient Factory Options 를 실현 한 다음 에 동적 으로 생 성 하 는 것 입 니 다.
    get_cert_handler_by_name 은 자신의 방법 입 니 다.업무 이름 a,b,c new handler 를 사용 하 는 지 여부 에 따라 다 를 수 있 습 니 다.
    그러나 이 모든 것 이 ServiceProvider 에서 HttpClient 를 가 져 오 면 이 사용자 정의 설정 클래스 로 이동 합 니 다.호환성 을 잘 해 야 합 니 다.
    
    class MyClass : IPostConfigureOptions<HttpClientFactoryOptions>
            {
                public void PostConfigure(string name, HttpClientFactoryOptions options)
                    => options.HttpMessageHandlerBuilderActions.Add(p => p.PrimaryHandler = get_cert_handler_by_name(name));
            }
    //      
    services.AddSingleton<Microsoft.Extensions.Options.IPostConfigureOptions<Microsoft.Extensions.Http.HttpClientFactoryOptions>, MyClass>();
    상술 한 것 은 몇 가지 전정 개요 이다.그러면 다음 에 우 리 는 이 수 요 를 실현 할 것 이다.
    초 에 한 가지 방법 을 생각하면 우 리 는 직접new HttpClient()할 수 있 고 매번 사용 할 때마다 직접 하 나 를 할 수 있다.간단 하고 거칠다.
    초 에 두 번 째 방법 을 생각 하거나 이름 에 따라 client 대상 을 캐 시 합 니 다.
    그러나 전자의 성능 은 문제 이 고 포트 의 점용 방출 문제 와 관련 되 어 호출 량 이 약간 많은 상황 에서 차 갑 고 후 자 는 이미 알 고 있 는 문제 가 있 습 니 다.HttpClient 대상 은 dns 의 변경 을 감지 할 수 없습니다.
    다른 더 믿 을 수 없 는 방법 은 코드 설정 방식Dictionary<string,HttpClient>을 사용 하여 모든 인증 서 를 설정 하고 모든 인증 서 를 설치 한 이 컴퓨터 에 신뢰 인증서 로 설정 하 는 것 이다.
    그렇다면 위의 이런 믿 을 수 없 는 방식(또는 치 명 적 인 결함 이 있 는 방식)을 제외 하고 믿 을 만 한 것 이 있 을 수 있 습 니까?물론 있 습 니 다.예 를 들 어 운행 시의 동적 배치 실현 방안 등 입 니 다.
    그래서 다음 에 제 가 두 가지 방식 을 추천 하 겠 습 니 다.바로 저희services.AddHttpClient("callback provider side").ConfigurePrimaryHttpMessageHandler()IHttpMessageHandlerBuilderFilter입 니 다.
    공식 적 으로 어떤 추천 이 있 습 니까?
    HttpClient 대상 에 인증 서 를 추가 하 는 방법 에 대해 공식 문서 의 실현 은 다음 과 같 습 니 다.인증서 와 IHttpClient Factory 의 이름 을 사용 하여 HttpClient 는 HttpClient 와 사용 인증서,HttpClient Handler 는 HttpClient 를 실현 합 니 다.그러나 여기 서 는 우리 가 실행 할 때 설정 한 수 요 를 해결 할 수 없 지만 단 서 를 제공 합 니 다.이름 설정 입 니 다.각각 다른 provider 에 사용자 정의 설정 을 제공 할 수 있 습 니 다.각각 다른 provider 가 실 행 될 때 설정 을 제공 할 수 있다 면 원본 읽 기 시간 입 니 다.
    다음 글 의 모든 코드 는 netcore 3.1 에서 왔 으 며,copy 키 코드 만 있 으 며,전체 코드 는 github 로 가서 볼 수 있 습 니 다.
    IHttpClient Factory.CreateClient 는 어떻게 HttpClient 를 만 들 었 습 니까?
  • 매번IPostConfigureOptions에 나 오 는 것 은 모두 새로운CreateClient사례
  • 이다.
  • HttpClient에 있 는CreateHandler은 우리 의 handler 를 캐 시 합 니 다.기본 값 은 2 분 입 니 다_activeHandlers.
  • 여기 서 한 가지 지식 이 있 습 니 다.만약 에 제 요청 이 기한 이 지나 기 전에 이 캐 시 대상 을 조금씩 얻 으 면 제 가 현재 요청 이 진행 되 고 있 을 수도 있 지만 2 분 이 지나 면 이 handler 는 회수 되 어야 합 니 다.그러면 공식 적 으로 이 가능 한 bug 를 어떻게 해결 하 는 지 보 세 요.글Cleaning up expired handlers을 보 세 요.저 는 긴 말 하지 않 겠 습 니 다.관건 은 하나HttpClientFactoryOptions.HandlerLifetime
  • 를 썼 다 는 것 이다.
  • WeakReference방법 은 우리 의 handlers 를 진정 으로 만 들 고 설정 하 는 곳 입 니 다.
  • CreateHandlerEntry에서 1 개IConfiguration대상
  • 얻 기
  • 응용HttpClientFactoryOptions
  • 응용IHttpMessageHandlerBuilderFilter
  • 
    //Microsoft.Extensions.Http.DefaultHttpClientFactory
    public HttpClient CreateClient(string name)
    {
    	HttpClient httpClient = new HttpClient(this.CreateHandler(name), disposeHandler: false);
    	return httpClient;
    }
    public HttpMessageHandler CreateHandler(string name)
    {
    	ActiveHandlerTrackingEntry value = this._activeHandlers.GetOrAdd(name, this._entryFactory).Value; 
            //_entryFactory        CreateHandlerEntry  .       Lazy<>(CreateHandlerEntry,LazyThreadSafetyMode.ExecutionAndPublication) ,           CreateHandlerEntry.
    	return value.Handler;
    }
    internal ActiveHandlerTrackingEntry CreateHandlerEntry(string name)
    {
            HttpClientFactoryOptions options = this._optionsMonitor.Get(name);
    	HttpMessageHandlerBuilder requiredService = provider.GetRequiredService<HttpMessageHandlerBuilder>();
    	requiredService.Name = name;
    	Action<HttpMessageHandlerBuilder> action = Configure; //      HttpClientFactoryOptions.HttpMessageHandlerBuilderActions
    	for (int num = this._filters.Length - 1; num >= 0; num--)
    	{
    		action = this._filters[num].Configure(action); //     _filters(       IEnumerable<IHttpMessageHandlerBuilderFilter> filters).
    	}
    	action(requiredService);
    	LifetimeTrackingHttpMessageHandler handler = new LifetimeTrackingHttpMessageHandler(requiredService.Build());
    	return new ActiveHandlerTrackingEntry(name, handler, serviceScope, options.HandlerLifetime);
    
    	void Configure(HttpMessageHandlerBuilder b)
    	{
    		for (int i = 0; i < options.HttpMessageHandlerBuilderActions.Count; i++)
    		{
    			options.HttpMessageHandlerBuilderActions[i](b);
    		}
    	}
    }
    관건 적 인 코드 는 바로 위 코드 에 표 시 된 확장 점 1 과 확장 점 2 이다.
  • 확장 점 1:적절 한 IHttpMessage Handler Builder Filter 대상 을 주입 하면HttpMessageHandlerBuilderActions대상 을 고 칠 수 있 고 우리 가 실행 할 때 동적 설정 을 실현 할 수 있 습 니 다.
  • 확장 점 2:사용자 정의 IConfiguration 설정 을 실현 해 야 합 니 다.requiredService받 은 대상 의this._optionsMonitor.Get(name)속성 에 해당 하 는 변경 코드 만 포함 하면 됩 니 다.
  • 확장 점 1 의 실현
    HttpClient 의 handler 에 설 정 된 filter 를 추가 합 니 다.handler Builder 에 맞 는 쓰기 논 리 를 추가 합 니 다.
    HttpClient 대상 을 사용 할 때 발생 하 는 로그("Sending HTTP request...","Received HTTP response headers after...")는 이 Filter 기능 에 의 해 주 입 됩 니 다.공식 참조 코드:LoggingHttpMessageHandlerBuilderFilter
    개인 적 인 견해:이 확장 점 에 이 업 무 를 추가 하 는 것 은 응용 장면 에 특별히 부합 되 지 않 는 다 고 생각 하기 때문에 저 는 확장 점 2 에서 이 일 을 하 는 것 을 권장 합 니 다.
    
    class MyHttpClientHandlerFilter : IHttpMessageHandlerBuilderFilter
    {
        public Action<HttpMessageHandlerBuilder> Configure(Action<HttpMessageHandlerBuilder> next)
        {
            void Configure(HttpMessageHandlerBuilder builder)
            {
                next(builder); //      next,        HandlerBuilder         call _filters,   call options.HttpMessageHandlerBuilderActions(    ).
    
                if (builder.Name.StartsWith("CallbackProviderSide-")) //                   ,           HttpClient   .
                {
                    //builder.PrimaryHandler= your custom handler.          .
                }
            }
            return Configure;
        }
    }
    //   DI        filter.
    ServiceCollection.AddSingleton<IHttpMessageHandlerBuilderFilter,MyHttpClientHandlerFilter>();
    확장 점 2 의 실현
    
    class MyHttpClientCustomConfigure : IPostConfigureOptions<HttpClientFactoryOptions>
    {
        public void PostConfigure(string name, HttpClientFactoryOptions options)
        {
            if (name.StartsWith("CallbackProviderSide-")) //                   ,           HttpClient   .
            {
                options.HttpMessageHandlerBuilderActions.Add(p =>
                {
                    //p.PrimaryHandler= your custom handler.          .
                });
            }
        }
    }
    
    //   DI               .
    ServiceCollection.AddSingleton<Microsoft.Extensions.Options.IPostConfigureOptions<Microsoft.Extensions.Http.HttpClientFactoryOptions>, MyHttpClientCustomConfigure>();
    왜 여기에 주 입 된 유형 은HttpMessageHandlerBuilderActions입 니까?Microsoft.Extensions.Options.IPostConfigureOptions<Microsoft.Extensions.Http.HttpClientFactoryOptions>구조 함수 에 필요 한 것 은 바로 이것 입 니 다.Configuration 시스템 의 확장 과 소스 코드 는 여기 서 전개 되 지 않 습 니 다.
    쓰다
    그것 을 사용 하 는 것 은 간단 하 다.
    
    var factory = ServiceProvider.GetService<IHttpClientFactory>();
    var httpClientForBaidu = factory.CreateClient("CallbackProviderSide-baidu");
    var httpClientForCnblogs = factory.CreateClient("CallbackProviderSide-Cnblogs");
    총괄 하 다
    이렇게 해서 우리 가 이 운행 할 때 HttpClient 를 동적 으로 설정 하면 완성 되 더 라 도 나 는 가볍게 문장 한 편 을 풀 었 다.
    또한OptionsFactory뒤의 이 야 기 는 글Exploring the code behind IHttpClientFactory in depth을 볼 수 있 고 완전한 절차 도 에 코드 를 붙 여 분명하게 설명 할 수 있다.
    이상 은 asp.net core 가 IHttpClient Factory 에 동적 이름 설정 을 추가 하 는 상세 한 내용 입 니 다.asp.net core 에 동적 이름 설정 을 추가 하 는 자 료 는 다른 글 을 주목 하 십시오!

    좋은 웹페이지 즐겨찾기