Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
Instance HttpClient třídy funguje jako relace pro odesílání požadavků HTTP. Instance HttpClient je kolekce nastavení použitá pro všechny požadavky spuštěné danou instancí. Každá instance navíc HttpClient používá vlastní fond připojení a izoluje své požadavky z požadavků spuštěných jinými HttpClient instancemi.
Vytváření instancí
HttpClient je určena k vytvoření instance jednou a opakovanému použití v průběhu celé životnosti aplikace. V .NET Core a .NET 5 nebo novějších, HttpClient uchovává připojení v instanci obslužné rutiny a znovu používá připojení pro více požadavků. Pokud vytvoříte instanci třídy HttpClient pro každý požadavek, počet síťových portů dostupných při velkém zatížení bude vyčerpán. Výsledek tohoto vyčerpání budou chyby SocketException.
Další možnosti můžete nakonfigurovat předáním "obslužné rutiny" jako součásti konstruktoru, například HttpClientHandler nebo SocketsHttpHandler (v .NET Core 2.1 nebo novější). Vlastnosti připojení v obslužné rutině nelze po odeslání požadavku změnit, takže jedním z důvodů vytvoření nové instance HttpClient by bylo, kdybyste potřebovali změnit vlastnosti připojení. Pokud různé požadavky vyžadují různá nastavení, může to také vést k tomu, že aplikace má více HttpClient instancí, kde je každá instance správně nakonfigurovaná, a pak se požadavky vydávají na příslušném klientovi.
HttpClient překládá pouze položky DNS při vytvoření připojení. Nesleduje dobu trvání TTL (Time To Live) určenou serverem DNS. Pokud se položky DNS mění pravidelně, což se může stát v některých scénářích kontejneru, klient tyto aktualizace nerespektuje. Chcete-li tento problém vyřešit, můžete omezit dobu životnosti připojení nastavením SocketsHttpHandler.PooledConnectionLifetime vlastnosti, aby při nahrazení připojení bylo vyžadováno vyhledávání DNS.
public class GoodController : ApiController
{
private static readonly HttpClient httpClient;
static GoodController()
{
var socketsHandler = new SocketsHttpHandler
{
PooledConnectionLifetime = TimeSpan.FromMinutes(2)
};
httpClient = new HttpClient(socketsHandler);
}
}
Jako alternativu k vytvoření pouze jedné instance HttpClient můžete také použít IHttpClientFactory ke správě instancí HttpClient za vás. Další informace naleznete v tématu Pokyny pro použití HttpClient.
Derivace
Funguje HttpClient také jako základní třída pro konkrétnější klienty HTTP. Příkladem může být FacebookHttpClient, který poskytuje další metody specifické pro webovou službu Facebooku (například metodu GetFriends ). Odvozené třídy by neměly překrývat virtuální metody v rámci třídy. Místo toho použijte přetížení konstruktoru, které přijímá HttpMessageHandler ke konfiguraci jakéhokoli předběžného požadavku nebo následného zpracování požadavku.
Přenosy
Jedná se HttpClient o rozhraní API vysoké úrovně, které zabalí funkce nižší úrovně dostupné na každé platformě, kde běží.
Na každé platformě HttpClient se pokusí použít nejlepší dostupnou dopravu:
| Host/runtime | Back-end |
|---|---|
| Windows/.NET Framework | HttpWebRequest |
| Windows/Mono | HttpWebRequest |
| Windows/UPW | Nativní Windows WinHttpHandler (podporující HTTP 2.0) |
| Windows/.NET Core 1.0-2.0 | Nativní Windows WinHttpHandler (podporující HTTP 2.0) |
| macOS/Mono | HttpWebRequest |
| macOS/.NET Core 1.0-2.0 |
libcurlna základě přenosu HTTP (podporuje HTTP 2.0) |
| Linux/Mono | HttpWebRequest |
| Linux/.NET Core 1.0-2.0 |
libcurlna základě přenosu HTTP (podporuje HTTP 2.0) |
| .NET Core 2.1 a novější | System.Net.Http.SocketsHttpHandler |
Uživatelé mohou také nakonfigurovat konkrétní přenos pro HttpClient tím, že vyvolají konstruktor HttpClient, který přebírá HttpMessageHandler.
.NET Framework & Mono
Ve výchozím nastavení se v rozhraní .NET Framework a Mono HttpWebRequest používá k odesílání požadavků na server. Toto chování lze upravit zadáním jiné obslužné rutiny v jednom z přetížení konstruktoru s parametrem HttpMessageHandler. Pokud požadujete funkce, jako je ověřování nebo ukládání do mezipaměti, můžete použít WebRequestHandler ke konfiguraci nastavení a instanci lze předat konstruktoru. Vrácenou obslužnou rutinu lze předat do přetížené verze konstruktoru HttpMessageHandler, který má parametr.
.NET Core
Počínaje rozhraním .NET Core 2.1 poskytuje třída System.Net.Http.SocketsHttpHandler místo HttpClientHandler implementaci používanou vyššími síťovými třídami HTTP, jako je HttpClient. Použití SocketsHttpHandler nabízí řadu výhod:
- Významné zlepšení výkonu v porovnání s předchozí implementací.
- Odstranění závislostí platformy, které zjednodušuje nasazení a údržbu. Například
libcurluž není závislost na .NET Core pro macOS a .NET Core pro Linux. - Konzistentní chování na všech platformách .NET
Pokud je tato změna nežádoucí, můžete ve Windows pokračovat v používání WinHttpHandler odkazováním na jeho balíček NuGet a jeho předáním do konstruktoru HttpClient ručně.
Konfigurace chování pomocí možností konfigurace modulu runtime
Některé aspekty HttpClientchování se dají přizpůsobit prostřednictvím možností konfigurace modulu runtime. Chování těchto přepínačů se ale liší v různých verzích .NET. Například v .NET Core 2.1 – 3.1 můžete nakonfigurovat, jestli SocketsHttpHandler se používá ve výchozím nastavení, ale tato možnost už není dostupná od .NET 5.
Sdružování připojení
HttpClient sloučí připojení HTTP, pokud je to možné, a používá je pro více než jeden požadavek. To může mít významné zvýšení výkonu, zejména pro požadavky HTTPS, protože navázání spojení se provádí pouze jednou.
Vlastnosti fondu připojení lze konfigurovat pro objekt HttpClientHandler nebo SocketsHttpHandler předané během konstrukce, včetně MaxConnectionsPerServer, PooledConnectionIdleTimeout a PooledConnectionLifetime.
Odstranění instance HttpClient zavře otevřená připojení a zruší všechny čekající požadavky.
Poznámka:
Pokud souběžně odesíláte požadavky HTTP/1.1 na stejný server, můžete vytvořit nová připojení. Pokud znovu použijete instanci HttpClient, může se stát, že kvůli výchozím časovačům čištění protokolu TCP budou vyčerpány dostupné sokety, zvláště když je rychlost požadavků vysoká nebo pokud existují omezení brány firewall. Chcete-li omezit počet souběžných připojení, můžete nastavit MaxConnectionsPerServer vlastnost. Ve výchozím nastavení je počet souběžných připojení HTTP/1.1 neomezený.
Ukládání do vyrovnávací paměti a životnost požadavků
Ve výchozím nastavení metody HttpClient (s výjimkou GetStreamAsync), vyrovnávají odpovědi ze serveru, které před vrácením asynchronního výsledku načtou celé tělo odpovědi do paměti. Tyto požadavky budou pokračovat, dokud nedojde k některému z následujících kroků:
- Task<TResult> uspěje a vrátí výsledek.
- Dosaženo je Timeout, v takovém případě bude Task<TResult> zrušena.
- Dostupný CancellationToken parametr aktivuje některé přetížené metody.
- CancelPendingRequests() se volá.
- HttpClient je zrušen.
Ukládání do vyrovnávací paměti pro jednotlivé požadavky můžete změnit pomocí parametru HttpCompletionOption dostupného v některých přetíženích metody. Tento argument lze použít k určení, jestli Task<TResult> se má považovat za dokončený po přečtení pouze hlaviček odpovědi nebo po přečtení a uložení obsahu odpovědi do vyrovnávací paměti.
Pokud vaše aplikace, která používá HttpClient a související třídy v System.Net.Http oboru názvů hodlá stáhnout velké objemy dat (50 megabajtů nebo více), měla by aplikace streamovat tyto soubory ke stažení a nepoužívat výchozí ukládání do vyrovnávací paměti. Pokud použijete výchozí ukládání do vyrovnávací paměti, bude využití paměti klienta velmi velké, což může mít za následek podstatně nižší výkon.
Bezpečnost vlákna
Následující metody jsou bezpečné pro přístup z více vláken:
- CancelPendingRequests
- DeleteAsync
- GetAsync
- GetByteArrayAsync
- GetStreamAsync
- GetStringAsync
- PostAsync
- PutAsync
- SendAsync
Proxy
Ve výchozím nastavení httpClient čte konfiguraci proxy serveru z proměnných prostředí nebo nastavení uživatele/systému v závislosti na platformě. Toto chování můžete změnit předáním WebProxy nebo IWebProxy podle pořadí důležitosti:
- Vlastnost Proxy httpClientHandler předána během vytváření HttpClient
- Statická DefaultProxy vlastnost (ovlivňuje všechny instance)
Proxy server můžete zakázat pomocí UseProxy. Výchozí konfigurací pro uživatele Windows je vyzkoušet a zjistit proxy pomocí zjišťování sítě, což může být pomalé. U aplikací s vysokou propustností, u kterých je známo, že proxy server není nutný, byste proxy měli zakázat.
Nastavení proxy serveru (například Credentials) by se mělo změnit pouze před provedením prvního požadavku pomocí HttpClient. Změny provedené po prvním použití HttpClient se nemusí v následných požadavcích projevit.
Časové limity
Můžete použít Timeout k nastavení výchozího časového limitu pro všechny požadavky HTTP z instance HttpClient. Časový limit se vztahuje pouze na metody xxxAsync, které způsobují zahájení požadavku nebo odpovědi. Pokud dojde k dosažení časového limitu Task<TResult> , zruší se žádost.
Pokud při vytváření objektu HttpClient předáte instanci SocketsHttpHandler, můžete nastavit další časové limity.
| Vlastnictví | Popis |
|---|---|
| ConnectTimeout | Určuje časový limit, který se použije, když požadavek vyžaduje vytvoření nového připojení TCP. Pokud dojde k vypršení časového limitu, žádost Task<TResult> se zruší. |
| PooledConnectionLifetime | Určuje časový limit, který se má použít pro každé připojení ve fondu připojení. Pokud je připojení nečinné, připojení je okamžitě uzavřeno; v opačném případě je připojení uzavřeno na konci aktuálního požadavku. |
| PooledConnectionIdleTimeout | Pokud je připojení ve fondu připojení takto dlouho nečinné, připojení se zavře. |
| Expect100ContinueTimeout | Pokud má požadavek hlavičku "Expect: 100-continue", zpožďuje odesílání obsahu dokud nevyprší časový limit nebo není přijata odpověď "100-continue". |
HttpClient překládá pouze položky DNS při vytváření připojení. Nesleduje dobu trvání TTL (Time To Live) určenou serverem DNS. Pokud se položky DNS pravidelně mění, což se může stát v některých scénářích kontejneru, můžete použít PooledConnectionLifetime k omezení doby životnosti připojení, aby se při nahrazení připojení vyžadovalo vyhledávání DNS.