ASP.Net Core 2.1 和 IHttpClientFactory 中的 Flurl 客户端生命周期

Posted

技术标签:

【中文标题】ASP.Net Core 2.1 和 IHttpClientFactory 中的 Flurl 客户端生命周期【英文标题】:Flurl client lifetime in ASP.Net Core 2.1 and IHttpClientFactory 【发布时间】:2018-12-04 20:22:09 【问题描述】:

Flurl 指出使用单例客户端是推荐的模式:

HttpClient 旨在被实例化一次并在应用程序的整个生命周期中重复使用。特别是在服务器应用程序中,为每个请求创建一个新的 HttpClient 实例将耗尽重负载下可用的套接字数量。这将导致 SocketException 错误。

但是从 Asp.Net Core 2.1 开始有updated rules for HttpClient lifetime in Net Core 2.1。

当你使用 HttpClientFactory 请求一个 HttpClient 时,实际上你每次都会得到一个新的实例,这意味着我们不必担心改变它的状态。此 HttpClient 可能(或可能不)使用池中现有的 HttpClientHandler,因此使用现有的打开连接。

如何修改 Flurl 以在后台使用 IHttpClientFactory?我应该创建自定义 Flurl 的 settings.HttpClientFactory 并通过 MS IHttpClientFactory 创建 HttpClient 吗?

【问题讨论】:

对于 ASP .Net 2.1 和 Flurl 2.0,无法按照 Todd Menier 的建议实例化 FlurlClient。 @RodrigoS.Teixeira 这在技术上是正确的,the constructor required to do it this way was introduced in Flurl.Http 2.3.1, released last April。有什么东西阻止你升级吗? 【参考方案1】:

首先,需要注意的是,MS 的新HttpClientFactory 旨在与 ASP.NET Core 2.1 及其内置的 DI 容器结合使用。如果您没有将FlurlClients 注入控制器或服务类,而是像这样使用 Flurl:

await url.GetJsonAsync();

那么它甚至不相关。您应该实施Flurl's IHttpClientFactory 来使用MS。它没有使用 DI 容器的正确上下文,您最终将求助于服务位置,这是一种反模式。您想要利用的那些新的套接字池功能实际上存在于较低级别:System.Net.Http.SocketsHttpHandler。 Flurl 默认使用 HttpClientHander 作为其消息处理程序,但幸运的是,它已在 .NET Core 2.1 中重写,默认情况下将其所有工作推迟到 SocketsHttpHandler。换句话说,如果您在 .NET Core 2.1 应用程序中使用 Flurl,那么您已经获得了 MS 一直在开发的所有新套接字管理功能

如果您正在在 ASP.NET Core 2.1 应用程序中显式使用 FlurlClient,作为 HttpClient 的替代品,并希望在利用MS的HttpClientFactory必须提供什么,我建议完全按照MS的规定在ConfigureServices中设置HttpClientFactory,当您需要FlurlClient实例时,使用采用HttpClient实例的构造函数。例如,当使用类型化客户端模式时,您的服务类可能如下所示:

public class MyService

    private readonly IFlurlClient _flurlClient;

    public MyService(HttpClient httpClient)
    
        _flurlClient = new FlurlClient(httpClient);
    

【讨论】:

抱歉删除这个非常老的答案,但我想知道:DefaultHttpClientFactory 在这里必须提供什么,因为您已经说过 Flurl 已经将套接字池和刷新 DNS 查询委托给BCL?鉴于ServiceCollection.AddHttp() 的重量,我有点不愿意使用它,除非它在 ​​Flurl 之上增加了一堆价值。 @NickCox 公平问题。 Flurl 的 HttpClientFactory 用途非常狭窄:它允许您控制 FlurlClient 使用的 HttpClient 和 HttpMessageHandler 的构造。它根本不关心缓存实例、重用套接字等。只关心构造细节。如果像上面的示例一样向 FlurlClient 构造函数提供 HttpClient,则根本不会使用它。它仅在您不使用时使用,并且 FlurlClient 会在需要时(懒惰地)调用一次。

以上是关于ASP.Net Core 2.1 和 IHttpClientFactory 中的 Flurl 客户端生命周期的主要内容,如果未能解决你的问题,请参考以下文章

小5聊Asp.Net Core 2.1 主要依赖那些dll和版本

ASP.NET Core 托管捆绑包 5 是不是也可以运行 .NET/ASP.NET Core 2.1 应用程序?

ASP.NET Core 2.1 中的 UseStaticFiles、UseSpaStaticFiles 和 UseSpa 有啥区别?

ASP Net Core 2.1 会话

ASP.NET Core 2.1 Razor 页面返回带有模型的页面

ASP.Net Core 2.1 中的身份< - 自定义 AccountController