『技术群里聊些啥』HttpClient 如何判断是同一终结点

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『技术群里聊些啥』HttpClient 如何判断是同一终结点相关的知识,希望对你有一定的参考价值。

前言

官方文档对 HttpClientHandler.MaxConnectionsPerServer 属性有如下说明:

获取或设置使用 HttpClient 对象发出请求时允许的最大并发连接数(每个服务器终结点)。请注意,该限制针对每个服务器终结点,例如,值为 256 表示允许 256 个到 http://www.adatum.com/ 的并发连接,以及另外 256 个到 http://www.adventure-works.com/ 的并发连接。

有网友在交流群中询问,终结点到底指的啥,怎么判断是同一终结点?

让我们通过源码来看看吧!

源码分析

HttpClientHandler.MaxConnectionsPerServer

HttpClientHandler.MaxConnectionsPerServer 的实现代码如下:

public int MaxConnectionsPerServer

    get => _underlyingHandler.MaxConnectionsPerServer;
    set => _underlyingHandler.MaxConnectionsPerServer = value;

实际使用的是_underlyingHandler.MaxConnectionsPerServer。而_underlyingHandlerSocketsHttpHandler类的实例:

using HttpHandlerType = System.Net.Http.SocketsHttpHandler;

private readonly HttpHandlerType _underlyingHandler;

SocketsHttpHandler.MaxConnectionsPerServer

SocketsHttpHandler.MaxConnectionsPerServer 的实现代码如下:

public int MaxConnectionsPerServer

    get => _settings._maxConnectionsPerServer;
    set
    
        ...

        _settings._maxConnectionsPerServer = value;
    

实际使用的是_settings._maxConnectionsPerServer。那么,谁在使用这个设置值呢?

HttpConnectionPool

我们定位到了HttpConnectionPool的构造函数:

public HttpConnectionPool(HttpConnectionPoolManager poolManager, HttpConnectionKind kind, string? host, int port, string? sslHostName, Uri? proxyUri)

    ...

    _maxHttp11Connections = Settings._maxConnectionsPerServer;

    ...

HttpConnectionPool的作用就是,提供到同一终结点的连接池。看来我们离真相越来越近了。

/// <summary>Provides a pool of connections to the same endpoint.</summary>
internal sealed class HttpConnectionPool : IDisposable

HttpConnectionPoolManager

HttpConnectionPool的构造函数只在HttpConnectionPoolManager类中被调用:

public ValueTask<HttpResponseMessage> SendAsyncCore(HttpRequestMessage request, Uri? proxyUri, bool async, bool doRequestAuth, bool isProxyConnect, CancellationToken cancellationToken)

    HttpConnectionKey key = GetConnectionKey(request, proxyUri, isProxyConnect);

    HttpConnectionPool? pool;
    while (!_pools.TryGetValue(key, out pool))
    
        pool = new HttpConnectionPool(this, key.Kind, key.Host, key.Port, key.SslHostName, key.ProxyUri);

可以看到,HttpConnectionPool是从ConcurrentDictionary _pools 中获取的,而key的值是HttpConnectionKey类型。

HttpConnectionKey

而 HttpConnectionKey 是这样判断是否相等的:

public readonly HttpConnectionKind Kind;
public readonly string? Host;
public readonly int Port;
public readonly string? SslHostName;     // null if not SSL
public readonly Uri? ProxyUri;
public readonly string Identity;

public bool Equals(HttpConnectionKey other) =>
                Kind == other.Kind &&
                Host == other.Host &&
                Port == other.Port &&
                ProxyUri == other.ProxyUri &&
                SslHostName == other.SslHostName &&
                Identity == other.Identity;

结论

由上面的代码,我们可以得出如下结论:

如果连接类型、服务器地址、服务器端口、代理(如果有)全部相同,则认为是同一终结点

添加微信号【MyIO666】,邀你加入技术交流群

以上是关于『技术群里聊些啥』HttpClient 如何判断是同一终结点的主要内容,如果未能解决你的问题,请参考以下文章

『技术群里聊些啥』Task 不是你想 Cancel,想 Cancel 就能 Cancel

『技术群里聊些啥』查看 dotnet 源码,用它!用它!用它!

番茄工作法

程序猿们,再不行动就来不及了!

.Net Core HttpClient处理响应压缩

程序员们,再不行动就来不及了!