Share via


System.Net.Http.HttpClient 클래스

이 문서에서는 이 API에 대한 참조 설명서에 대한 추가 설명서를 제공합니다.

클래스 인스턴스는 HttpClient HTTP 요청을 보내는 세션 역할을 합니다. HttpClient 인스턴스는 해당 인스턴스에서 실행된 모든 요청에 적용되는 설정 컬렉션입니다. 또한 모든 HttpClient 인스턴스는 자체 연결 풀을 사용하여 다른 HttpClient 인스턴스에서 실행된 요청에서 해당 요청을 격리합니다.

인스턴스 만들기

HttpClient 는 애플리케이션의 수명 동안 한 번 인스턴스화되고 다시 사용되도록 의도된 것입니다. .NET Core 및 .NET 5 이상에서 HttpClient는 처리기 인스턴스 내부의 연결을 풀하고 여러 요청에서 연결을 다시 사용합니다. 모든 요청에 대해 HttpClient 클래스를 인스턴스화하면 부하가 많은 상태에서 사용할 수 있는 소켓 수가 소진됩니다. 이 고갈로 인해 오류가 발생합니다 SocketException .

생성자의 일부로 "처리기"(예SocketsHttpHandler: HttpClientHandler .NET Core 2.1 이상)를 전달하여 추가 옵션을 구성할 수 있습니다. 요청이 제출되면 처리기의 연결 속성을 변경할 수 없으므로 새 HttpClient 인스턴스를 만드는 한 가지 이유는 연결 속성을 변경해야 하는 경우입니다. 요청마다 다른 설정이 필요한 경우 각 인스턴스가 적절하게 구성된 여러 HttpClient 인스턴스가 있는 애플리케이션이 관련 클라이언트에서 요청이 발급될 수도 있습니다.

HttpClient는 연결이 만들어지는 경우에만 DNS 항목을 확인합니다. DNS 서버에서 지정한 TTL(Time to Live) 기간을 추적하지 않습니다. 일부 컨테이너 시나리오에서 발생할 수 있는 DNS 항목이 정기적으로 변경되는 경우 클라이언트는 이러한 업데이트를 존중하지 않습니다. 이 문제를 해결하려면 연결을 바꿀 때 DNS 조회가 필요하도록 속성을 설정 SocketsHttpHandler.PooledConnectionLifetime 하여 연결의 수명을 제한할 수 있습니다.

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

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

        httpClient = new HttpClient(socketsHandler);
    }
}

HttpClient 인스턴스를 하나만 만드는 대신 HttpClient 인스턴스를 관리하는 데 사용할 IHttpClientFactory 수도 있습니다. 자세한 내용은 HttpClient 사용 지침을 참조하세요.

파생 상품

또한 더 HttpClient 구체적인 HTTP 클라이언트에 대한 기본 클래스로도 작동합니다. 예를 들어 Facebook 웹 서비스와 관련된 추가 메서드(예: 메서드)를 제공하는 FacebookHttpClient가 GetFriends 있습니다. 파생 클래스는 클래스의 가상 메서드를 재정의해서는 안 됩니다. 대신 사전 요청 또는 사후 요청 처리를 구성하는 데 허용하는 HttpMessageHandler 생성자 오버로드를 사용합니다.

전송

HttpClient API는 실행되는 각 플랫폼에서 사용할 수 있는 하위 수준 기능을 래핑하는 상위 수준 API입니다.

각 플랫폼에서 HttpClient 사용 가능한 최상의 전송을 사용하려고 합니다.

호스트/런타임 백 엔드
Windows/.NET Framework HttpWebRequest
Windows/Mono HttpWebRequest
Windows/UWP Windows 네이티브 WinHttpHandler (HTTP 2.0 지원)
Windows/.NET Core 1.0-2.0 Windows 네이티브 WinHttpHandler (HTTP 2.0 지원)
Android/Xamarin 빌드 시 선택됩니다. Android의 네이티브를 사용 HttpWebRequest 하거나 사용하도록 구성할 수 있습니다. HttpURLConnection
iOS, tvOS, watchOS/Xamarin 빌드 시 선택됩니다. Apple을 NSUrlSession 사용하거나 사용하도록 HttpWebRequest 구성할 수 있습니다(HTTP 2.0 지원)
macOS/Xamarin 빌드 시 선택됩니다. Apple을 NSUrlSession 사용하거나 사용하도록 HttpWebRequest 구성할 수 있습니다(HTTP 2.0 지원)
macOS/Mono HttpWebRequest
macOS/.NET Core 1.0-2.0 libcurl-based HTTP 전송(HTTP 2.0 지원)
Linux/Mono HttpWebRequest
Linux/.NET Core 1.0-2.0 libcurl-based HTTP 전송(HTTP 2.0 지원)
.NET Core 2.1 이상 System.Net.Http.SocketsHttpHandler

사용자는 을 사용하는 생성자를 호출하여 특정 전송 HttpClientHttpClient 구성할 수도 있습니다 HttpMessageHandler.

.NET Framework 및 Mono

기본적으로 .NET Framework 및 Mono HttpWebRequest 는 서버에 요청을 보내는 데 사용됩니다. 이 동작은 매개 변수를 사용하여 생성자 오버로드 중 하나에서 다른 처리기를 지정하여 수정할 수 있습니다 HttpMessageHandler . 인증 또는 캐싱과 같은 기능이 필요한 경우 설정을 구성하는 데 사용할 WebRequestHandler 수 있으며 인스턴스를 생성자에 전달할 수 있습니다. 반환된 처리기는 매개 변수가 있는 생성자 오버로드에 HttpMessageHandler 전달할 수 있습니다.

.NET Core

.NET Core 2.1 System.Net.Http.SocketsHttpHandler 부터 클래스는 HttpClientHandler 같은 상위 수준의 HTTP 네트워킹 클래스에서 사용하는 구현을 HttpClient대신 제공합니다. 사용 SocketsHttpHandler 은 다음과 같은 여러 가지 이점을 제공합니다.

  • 이전 구현보다 월등히 향상된 성능.
  • 배포 및 서비스를 간소화하는 플랫폼 종속성을 제거합니다. 예를 들어 libcurl 더 이상 macOS용 .NET Core 및 Linux용 .NET Core에 대한 종속성이 없습니다.
  • 모든 .NET 플랫폼에서 일관된 동작.

이 변경이 바람직하지 않은 경우 Windows에서는 해당 NuGet 패키지를 참조하고 HttpClient의 생성자에 수동으로 전달하여 계속 사용할 WinHttpHandler 수 있습니다.

런타임 구성 옵션을 사용하여 동작 구성

동작의 HttpClient특정 측면은 런타임 구성 옵션을 통해 사용자 지정할 수 있습니다. 그러나 이러한 스위치의 동작은 .NET 버전마다 다릅니다. 예를 들어 .NET Core 2.1 - 3.1에서 기본적으로 사용되는지 여부를 SocketsHttpHandler 구성할 수 있지만 해당 옵션은 .NET 5부터 더 이상 사용할 수 없습니다.

연결 풀링

HttpClient는 가능한 경우 HTTP 연결을 풀하고 둘 이상의 요청에 사용합니다. 연결 핸드셰이크가 한 번만 수행되므로 이는 특히 HTTPS 요청의 경우 상당한 성능 이점을 얻을 수 있습니다.

커넥트ion 풀 속성을 구성 HttpClientHandler 하거나 SocketsHttpHandler 생성 중에 전달될 수 있습니다(예MaxConnectionsPerServer: , PooledConnectionIdleTimeoutPooledConnectionLifetime).

HttpClient 인스턴스를 삭제하면 열려 있는 연결이 닫히고 보류 중인 요청이 취소됩니다.

참고 항목

동일한 서버에 HTTP/1.1 요청을 동시에 보내는 경우 새 연결을 만들 수 있습니다. 인스턴스를 HttpClient 다시 사용하는 경우에도 요청 속도가 높거나 방화벽 제한 사항이 있는 경우 기본 TCP 클린업 타이머로 인해 사용 가능한 소켓을 소진할 수 있습니다. 동시 연결 수를 제한하려면 속성을 설정할 MaxConnectionsPerServer 수 있습니다. 기본적으로 동시 HTTP/1.1 연결 수는 무제한입니다.

버퍼링 및 요청 수명

기본적으로 HttpClient 메서드(제외 GetStreamAsync)는 비동기 결과를 반환하기 전에 모든 응답 본문을 메모리로 읽어 서버의 응답을 버퍼링합니다. 이러한 요청은 다음 중 하나가 발생할 때까지 계속됩니다.

일부 메서드 오버로드에서 사용할 수 있는 매개 변수를 사용하여 HttpCompletionOption 요청별로 버퍼링 동작을 변경할 수 있습니다. 이 인수는 응답 헤더만 읽은 후 또는 응답 콘텐츠를 읽고 버퍼링한 후에 완료로 간주되어야 하는지 여부를 Task<TResult> 지정하는 데 사용할 수 있습니다.

네임스페이스의 System.Net.Http 사용 및 관련 클래스를 사용하는 HttpClient 앱이 대량의 데이터(50MB 이상)를 다운로드하려는 경우 앱은 해당 다운로드를 스트리밍하고 기본 버퍼링을 사용하지 않아야 합니다. 기본 버퍼링을 사용하는 경우 클라이언트 메모리 사용량이 매우 커져 성능이 크게 저하될 수 있습니다.

스레드로부터의 안전성

다음 메서드는 스레드로부터 안전합니다.

프록시

기본적으로 HttpClient는 플랫폼에 따라 환경 변수 또는 사용자/시스템 설정에서 프록시 구성을 읽습니다. 우선 순위에 따라 전달 WebProxy 하거나 IWebProxy 전달하여 이 동작을 변경할 수 있습니다.

  • Proxy HttpClient 생성 중에 전달된 HttpClientHandler의 속성
  • DefaultProxy 정적 속성(모든 인스턴스에 영향을 줍니다.)

를 사용하여 UseProxy프록시를 사용하지 않도록 설정할 수 있습니다. Windows 사용자의 기본 구성은 네트워크 검색을 사용하여 프록시를 시도하고 검색하는 것이며, 속도가 느려질 수 있습니다. 프록시가 필요하지 않다고 알려진 높은 처리량 애플리케이션의 경우 프록시를 사용하지 않도록 설정해야 합니다.

프록시 설정(예: Credentials)은 HttpClient를 사용하여 첫 번째 요청이 이루어지기 전에만 변경해야 합니다. HttpClient를 처음 사용한 후 변경한 내용은 후속 요청에 반영되지 않을 수 있습니다.

시간 제한

HttpClient 인스턴스의 모든 HTTP 요청에 대한 기본 시간 제한을 설정하는 데 사용할 Timeout 수 있습니다. 시간 제한은 요청/응답을 시작하는 xxxAsync 메서드에만 적용됩니다. 시간 제한에 도달 Task<TResult> 하면 해당 요청에 대한 요청이 취소됩니다.

HttpClient 개체를 생성할 때 인스턴스를 SocketsHttpHandler 전달하는 경우 몇 가지 추가 시간 제한을 설정할 수 있습니다.

속성 설명
ConnectTimeout 요청에 새 TCP 연결을 만들어야 하는 경우 사용되는 시간 제한을 지정합니다. 시간 제한이 발생하면 요청 Task<TResult> 이 취소됩니다.
PooledConnectionLifetime 연결 풀의 각 연결에 사용할 시간 제한을 지정합니다. 연결이 유휴 상태이면 연결이 즉시 닫힙니다. 그렇지 않으면 현재 요청이 끝날 때 연결이 닫힙니다.
PooledConnectionIdleTimeout 연결 풀의 연결이 오랫동안 유휴 상태이면 연결이 닫힙니다.
Expect100ContinueTimeout 요청에 "Expect: 100-continue" 헤더가 있는 경우 시간 제한까지 또는 "100-continue" 응답이 수신될 때까지 콘텐츠 전송이 지연됩니다.

HttpClient는 연결이 만들어지는 경우에만 DNS 항목을 확인합니다. DNS 서버에서 지정한 TTL(Time to Live) 기간을 추적하지 않습니다. 일부 컨테이너 시나리오에서 발생할 수 있는 DNS 항목이 정기적으로 변경되는 경우 연결을 바꿀 때 DNS 조회가 필요하도록 연결의 수명을 제한하는 데 사용할 PooledConnectionLifetime 수 있습니다.