System.Net.Http.HttpClient osztály

Megjegyzés:

Ez a cikk kiegészítő megjegyzéseket tartalmaz az API referenciadokumentációjához.

Az HttpClient osztálypéldány munkamenetként működik a HTTP-kérések küldéséhez. A HttpClient példányok az adott példány által végrehajtott összes kérésre alkalmazott beállítások gyűjteményei. Emellett minden HttpClient példány saját kapcsolatkészletet használ, elkülönítve a más HttpClient példányok által végrehajtott kérelmektől érkező kéréseket.

Példányosítás

HttpClient példányosítható, és az alkalmazás teljes élettartama alatt újra felhasználható. A .NET Core-ban és a .NET 5+-ban a kezelőpéldány kapcsolatokat készletez, és egy kapcsolatot több kérés között újra felhasznál. Ha minden kéréshez létrehoz egy HttpClient osztályt, a nagy terhelés alatt elérhető foglalatok száma kimerül. Ez a kimerültség hibákat fog eredményezni SocketException .

További beállításokat úgy konfigurálhat, hogy átad egy "kezelőt", például HttpClientHandler (vagy SocketsHttpHandler a .NET Core 2.1-ben vagy újabb verzióban) a konstruktor részeként. A kezelő kapcsolati tulajdonságai nem módosíthatók a kérés elküldése után, ezért az új HttpClient példány létrehozásának egyik oka az lenne, ha módosítania kell a kapcsolat tulajdonságait. Ha a különböző kérések eltérő beállításokat igényelnek, ez azt is eredményezheti, hogy egy alkalmazás több HttpClient példányból áll, ahol az egyes példányok megfelelően vannak konfigurálva, majd a kérelmeket a megfelelő ügyfélen adják ki.

HttpClient csak kapcsolat létrehozásakor oldja fel a DNS-bejegyzéseket. A DNS-kiszolgáló által megadott élettartamokat (TTL) nem követi nyomon. Ha a DNS-bejegyzések rendszeresen változnak, ami bizonyos tárolóforgatókönyvekben előfordulhat, az ügyfél nem fogja tiszteletben tartani ezeket a frissítéseket. A probléma megoldásához a tulajdonság beállításával SocketsHttpHandler.PooledConnectionLifetime korlátozhatja a kapcsolat élettartamát, így a kapcsolat cseréjekor DNS-keresésre van szükség.

public class GoodController : ApiController
{
    private static readonly HttpClient httpClient;

    static GoodController()
    {
        var socketsHandler = new SocketsHttpHandler
        {
            PooledConnectionLifetime = TimeSpan.FromMinutes(2)
        };

        httpClient = new HttpClient(socketsHandler);
    }
}

Alternatívaként ahelyett, hogy csak egy HttpClient példányt hozna létre, a IHttpClientFactory-et is használhatja a HttpClient példányok kezelésére. További információkért tekintse meg a HttpClient használatának irányelveit.

Levezetés

Ez HttpClient alaposztályként is működik konkrétabb HTTP-ügyfelek számára. Például egy FacebookHttpClient, amely további, kifejezetten a Facebook-webszolgáltatáshoz kötődő metódusokat biztosít (például egy GetFriends metódus). A származtatott osztályok nem bírálhatják felül az osztály virtuális metódusát. Ehelyett használjon olyan konstruktor túlterhelést, amely elfogadja a HttpMessageHandler-t bármilyen előzetes vagy utólagos kérésfeldolgozás konfigurálásához.

Szállítások

Ez HttpClient egy magas szintű API, amely az egyes platformokon elérhető alacsonyabb szintű funkciókat burkolja, ahol fut.

Minden platformon HttpClient a legjobban elérhető átvitelt próbálja használni:

Hoszt/futtatási környezet háttérrendszer
Windows/.NET-keretrendszer HttpWebRequest
Windows/Mono HttpWebRequest
Windows/UWP Windows natív WinHttpHandler (HTTP 2.0-kompatibilis)
Windows/.NET Core 1.0-2.0 Windows natív WinHttpHandler (HTTP 2.0-kompatibilis)
macOS/Mono HttpWebRequest
macOS/.NET Core 1.0-2.0 libcurl-alapú HTTP-átvitel (HTTP 2.0 képes)
Linux/Mono HttpWebRequest
Linux/.NET Core 1.0-2.0 libcurl-alapú HTTP-átvitel (HTTP 2.0 képes)
.NET Core 2.1 és újabb verziók System.Net.Http.SocketsHttpHandler

A felhasználók konfigurálhatnak egy adott átvitelt HttpClient a HttpClient konstruktor meghívásával, amelyik egy HttpMessageHandler elfogad.

.NET-keretrendszer > Mono

Alapértelmezés szerint a .NET-keretrendszeren és a Mono-n HttpWebRequest a rendszer kéréseket küld a kiszolgálónak. Ez a viselkedés módosítható azáltal, hogy megad egy másik kezelőt az egyik HttpMessageHandler paraméterrel túlterhelt konstruktorban. Ha olyan funkciókra van szüksége, mint a hitelesítés vagy a gyorsítótárazás, a WebRequestHandler segítségével konfigurálhatja a beállításokat, és az így kapott példány átadható a konstruktornak. A visszaadott kezelő átadható egy paraméterrel rendelkező HttpMessageHandler konstruktor túlterhelésének.

.NET Core

A .NET Core 2.1-től kezdve az System.Net.Http.SocketsHttpHandler osztály adja az implementációt, amelyet a magasabb szintű HTTP-hálózati osztályok, például a HttpClientHandler használnak HttpClient helyett. A használat SocketsHttpHandler számos előnnyel jár:

  • Jelentős teljesítménybeli javulás az előző implementációhoz képest.
  • A platformfüggőségek megszüntetése, ami leegyszerűsíti az üzembe helyezést és a karbantartást. Például libcurl már nem függ a .NET Core for macOS és a .NET Core for Linux rendszertől.
  • Konzisztens viselkedés az összes .NET-platformon.

Ha ez a módosítás nem kívánatos, Windows rendszeren továbbra is használhatja a WinHttpHandler, ha hivatkozik a NuGet-csomagra, és manuálisan adja át azt a HttpClient konstruktorának.

Viselkedés konfigurálása futtatókörnyezet konfigurációs beállításaival

A viselkedés bizonyos aspektusai HttpClienta futtatókörnyezet konfigurációs beállításaival testreszabhatók. Ezeknek a kapcsolóknak a viselkedése azonban a .NET-verziókon keresztül eltérő. A .NET Core 2.1–3.1-ben például beállíthatja, hogy alapértelmezés szerint használják-e SocketsHttpHandler , de ez a beállítás már nem érhető el a .NET 5-ben.

Kapcsolatmegosztás

HttpClient ha lehetséges, HTTP-kapcsolatokat hoz létre, és egynél több kéréshez használja őket. Ez jelentős teljesítménybeli előnyökkel járhat, különösen a HTTPS-kérelmek esetében, mivel a kapcsolat kézfogása csak egyszer történik.

A kapcsolatpool tulajdonságai konfigurálhatók a konstrukció során átadott HttpClientHandler, SocketsHttpHandler, MaxConnectionsPerServer, PooledConnectionIdleTimeout és PooledConnectionLifetime elemekre.

A(z) HttpClient példány törlése bezárja a nyitott kapcsolatokat, és megszakítja a függőben lévő kéréseket.

Megjegyzés:

Ha egyidejűleg HTTP/1.1 kéréseket küld ugyanarra a kiszolgálóra, új kapcsolatok hozhatók létre. Még akkor is, ha újra felhasználja a HttpClient példányt, ha a kérések aránya magas, vagy ha vannak tűzfalkorlátozások, amelyek kimeríthetik az elérhető szoftvercsatornákat az alapértelmezett TCP-tisztítási időzítők miatt. Az egyidejű kapcsolatok számának korlátozásához beállíthatja a tulajdonságot MaxConnectionsPerServer . Alapértelmezés szerint az egyidejű HTTP/1.1 kapcsolatok száma korlátlan.

Pufferelés és kérelem élettartama

Alapértelmezés szerint a HttpClient metódusok (kivéve GetStreamAsync) pufferelik a kiszolgáló válaszait, és az összes választörzset beolvasják a memóriába, mielőtt visszaadják az aszinkron eredményt. Ezek a kérések mindaddig folytatódnak, amíg az alábbiak valamelyike nem következik be:

A pufferelési viselkedést kérelemenként módosíthatja az HttpCompletionOption egyes metódusok túlterhelése esetén elérhető paraméter használatával. Ezzel az argumentummal megadhatja, hogy a Task<TResult> válaszfejlécek olvasása vagy a választartalom beolvasása és pufferelése után befejezettnek kell-e tekinteni.

Ha a névtérben HttpClient használt és kapcsolódó osztályokat használó System.Net.Http alkalmazás nagy mennyiségű adatot (50 megabájt vagy több) kíván letölteni, akkor az alkalmazásnak streamelnie kell ezeket a letöltéseket, és nem kell használnia az alapértelmezett pufferelést. Ha az alapértelmezett pufferelést használja, az ügyfél memóriahasználata nagyon nagy lesz, ami jelentősen csökkentheti a teljesítményt.

Szálbiztonság

A következő módszerek szálbiztosak:

proxyk

Alapértelmezés szerint beolvassa a HttpClient proxykonfigurációt a környezeti változókból vagy a felhasználói/rendszerbeállításokból a platformtól függően. Ezt a viselkedést módosíthatja úgy, hogy WebProxy vagy IWebProxy értéket ad át a következő sorrendben:

  • A Proxy tulajdonság az HttpClientHandler konstrukciója során átadva HttpClient
  • A DefaultProxy statikus tulajdonság (az összes példányt érinti)

A proxyt letilthatja a következővel UseProxy: . A Windows-felhasználók alapértelmezett konfigurációja a proxy észlelése a hálózatfelderítés használatával, ami lassú lehet. Az olyan nagy átviteli sebességű alkalmazások esetében, ahol ismert, hogy nincs szükség proxyra, tiltsa le a proxyt.

A proxybeállításokat (például Credentials) csak azelőtt kell módosítani, hogy az első kérés a HttpClient használatával megtörténik. Előfordulhat, hogy az HttpClient első használat után végrehajtott módosítások nem jelennek meg a későbbi kérésekben.

Időtúllépések

A Timeout segítségével beállíthat egy alapértelmezett időtúllépést a HttpClient példány összes HTTP-kérésére. Az időtúllépés csak azokra az xxxAsync metódusokra vonatkozik, amelyek a kérés/válasz kezdeményezését okozzák. Ha az időkorlát túllépésre kerül, a Task<TResult> kérelem törlésre kerül.

További időtúllépéseket is beállíthat, ha egy példányt SocketsHttpHandler ad át az HttpClient objektum létrehozásakor:

Ingatlan Leírás
ConnectTimeout Olyan időtúllépést ad meg, amely akkor használatos, ha egy kéréshez új TCP-kapcsolat szükséges. Ha időtúllépés bekövetkezik, a kérés Task<TResult> lemondásra kerül.
PooledConnectionLifetime A csatlakozási készlet minden egyes kapcsolatára alkalmazandó időtúllépést határoz meg. Ha a kapcsolat tétlen, a kapcsolat azonnal bezárul; ellenkező esetben a kapcsolat az aktuális kérés végén lezárul.
PooledConnectionIdleTimeout Ha egy kapcsolat a kapcsolatkészletben ilyen hosszú ideig tétlen, a kapcsolat lezárul.
Expect100ContinueTimeout Ha a kérés "Expect: 100-continue" fejléccel rendelkezik, késlelteti a tartalom küldését, amíg az időtúllépés be nem következik, vagy amíg meg nem érkezik a "100-continue" válasz.

HttpClient csak a kapcsolatok létrehozásakor oldja fel a DNS-bejegyzéseket. A DNS-kiszolgáló által megadott élettartamokat (TTL) nem követi nyomon. Ha a DNS-bejegyzések rendszeresen változnak, ami egyes tárolóforgatókönyvekben előfordulhat, akkor a PooledConnectionLifetime segítségével korlátozhatja a kapcsolat élettartamát, így a DNS-keresés a kapcsolat cseréjekor válik szükségessé.