HttpClientFactory.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using FastGithub.Configuration;
  2. using FastGithub.DomainResolve;
  3. using System;
  4. using System.Collections.Concurrent;
  5. namespace FastGithub.Http
  6. {
  7. /// <summary>
  8. /// HttpClient工厂
  9. /// </summary>
  10. sealed class HttpClientFactory : IHttpClientFactory
  11. {
  12. private readonly IDomainResolver domainResolver;
  13. /// <summary>
  14. /// 首次生命周期
  15. /// </summary>
  16. private readonly TimeSpan firstLiftTime = TimeSpan.FromSeconds(10d);
  17. /// <summary>
  18. /// 非首次生命周期
  19. /// </summary>
  20. private readonly TimeSpan nextLifeTime = TimeSpan.FromMinutes(1d);
  21. /// <summary>
  22. /// LifetimeHttpHandler清理器
  23. /// </summary>
  24. private readonly LifetimeHttpHandlerCleaner httpHandlerCleaner = new();
  25. /// <summary>
  26. /// LazyOf(LifetimeHttpHandler)缓存
  27. /// </summary>
  28. private readonly ConcurrentDictionary<DomainConfig, Lazy<LifetimeHttpHandler>> httpHandlerLazyCache = new();
  29. /// <summary>
  30. /// HttpClient工厂
  31. /// </summary>
  32. /// <param name="domainResolver"></param>
  33. public HttpClientFactory(IDomainResolver domainResolver)
  34. {
  35. this.domainResolver = domainResolver;
  36. }
  37. /// <summary>
  38. /// 创建httpClient
  39. /// </summary>
  40. /// <param name="domainConfig"></param>
  41. /// <returns></returns>
  42. public HttpClient CreateHttpClient(DomainConfig domainConfig)
  43. {
  44. var lifetimeHttpHandlerLazy = this.httpHandlerLazyCache.GetOrAdd(domainConfig, CreateLifetimeHttpHandlerLazy);
  45. var lifetimeHttpHandler = lifetimeHttpHandlerLazy.Value;
  46. return new HttpClient(lifetimeHttpHandler, disposeHandler: false);
  47. Lazy<LifetimeHttpHandler> CreateLifetimeHttpHandlerLazy(DomainConfig domainConfig)
  48. {
  49. return new Lazy<LifetimeHttpHandler>(() => this.CreateLifetimeHttpHandler(domainConfig, this.firstLiftTime), true);
  50. }
  51. }
  52. /// <summary>
  53. /// 当有httpHandler失效时
  54. /// </summary>
  55. /// <param name="lifetimeHttpHandler">httpHandler</param>
  56. private void OnLifetimeHttpHandlerDeactivate(LifetimeHttpHandler lifetimeHttpHandler)
  57. {
  58. var domainConfig = lifetimeHttpHandler.DomainConfig;
  59. this.httpHandlerLazyCache[domainConfig] = CreateLifetimeHttpHandlerLazy(domainConfig);
  60. this.httpHandlerCleaner.Add(lifetimeHttpHandler);
  61. Lazy<LifetimeHttpHandler> CreateLifetimeHttpHandlerLazy(DomainConfig domainConfig)
  62. {
  63. return new Lazy<LifetimeHttpHandler>(() => this.CreateLifetimeHttpHandler(domainConfig, this.nextLifeTime), true);
  64. }
  65. }
  66. /// <summary>
  67. /// 创建LifetimeHttpHandler
  68. /// </summary>
  69. /// <param name="domainConfig"></param>
  70. /// <param name="lifeTime"></param>
  71. /// <returns></returns>
  72. private LifetimeHttpHandler CreateLifetimeHttpHandler(DomainConfig domainConfig, TimeSpan lifeTime)
  73. {
  74. var httpClientHandler = new HttpClientHandler(domainConfig, this.domainResolver);
  75. return new LifetimeHttpHandler(httpClientHandler, lifeTime, this.OnLifetimeHttpHandlerDeactivate);
  76. }
  77. }
  78. }