Bagikan melalui


Kelas System.Net.Http.HttpClient

Nota

Artikel ini menyediakan keterangan tambahan untuk dokumentasi referensi untuk API ini.

Instans HttpClient kelas bertindak sebagai sesi untuk mengirim permintaan HTTP. Instans HttpClient adalah kumpulan pengaturan yang diterapkan ke semua permintaan yang dijalankan oleh instans tersebut. Selain itu, setiap HttpClient instans menggunakan kumpulan koneksinya sendiri, mengisolasi permintaannya dari permintaan yang dijalankan oleh instans lain HttpClient .

Pembentukan Instance

HttpClient dimaksudkan untuk diinstansiasi sekali dan digunakan kembali selama masa pakai aplikasi. Di .NET Core dan .NET 5+, HttpClient mengelola kumpulan koneksi di dalam instans pengendali dan menggunakan koneksi kembali di beberapa permintaan. Jika Anda menginstansiasi sebuah kelas HttpClient untuk setiap permintaan, jumlah soket yang tersedia akan habis ketika berada di bawah beban berat. Kelelahan ini akan mengakibatkan SocketException kesalahan.

Anda dapat mengonfigurasi opsi tambahan dengan menspesifikasikan "handler", contohnya HttpClientHandler (atau SocketsHttpHandler di .NET Core 2.1 atau yang lebih baru), sebagai bagian dari konstruktor. Properti koneksi pada handler tidak dapat diubah setelah permintaan dikirimkan, jadi salah satu alasan untuk membuat instans baru HttpClient adalah jika Anda perlu mengubah properti koneksi. Jika permintaan yang berbeda memerlukan pengaturan yang berbeda, ini juga dapat menyebabkan aplikasi memiliki beberapa HttpClient instans, di mana setiap instans dikonfigurasi dengan tepat, lalu permintaan dikeluarkan pada klien yang relevan.

HttpClient hanya menyelesaikan entri DNS saat koneksi dibuat. Ini tidak melacak waktu hidup (TTL) yang ditentukan oleh server DNS. Jika entri DNS berubah secara teratur, yang dapat terjadi dalam beberapa skenario kontainer, klien tidak akan menghormati pembaruan tersebut. Untuk mengatasi masalah ini, Anda dapat membatasi masa pakai koneksi dengan mengatur SocketsHttpHandler.PooledConnectionLifetime properti , sehingga pencarian DNS diperlukan saat koneksi diganti.

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

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

        httpClient = new HttpClient(socketsHandler);
    }
}

Sebagai alternatif untuk membuat hanya satu HttpClient instans, Anda juga dapat menggunakan IHttpClientFactory untuk mengelola HttpClient instans untuk Anda. Untuk informasi selengkapnya, lihat Panduan untuk menggunakan HttpClient.

Derivasi

juga HttpClient bertindak sebagai kelas dasar untuk klien HTTP yang lebih spesifik. Contohnya adalah FacebookHttpClient yang menyediakan metode tambahan khusus untuk layanan web Facebook (misalnya, GetFriends metode ). Kelas turunan tidak boleh mengambil alih metode virtual pada kelas . Sebagai gantinya, gunakan overload konstruktor yang menerima HttpMessageHandler untuk mengonfigurasi pemrosesan pra-permintaan atau pasca-permintaan.

Transportasi

HttpClient adalah API tingkat tinggi yang membungkus fungsionalitas tingkat bawah yang tersedia di setiap platform tempatnya berjalan.

Pada setiap platform, HttpClient mencoba menggunakan transportasi terbaik yang tersedia:

Host/Runtime Backend
Windows/.NET Framework HttpWebRequest
Windows/Mono HttpWebRequest
Windows/UWP Windows native WinHttpHandler (mendukung HTTP 2.0)
Windows/.NET Core 1.0-2.0 Windows native WinHttpHandler (mendukung HTTP 2.0)
macOS/Mono HttpWebRequest
macOS/.NET Core 1.0-2.0 Transport HTTP berbasis libcurl (mendukung HTTP 2.0)
Linux/Mono HttpWebRequest
Linux/.NET Core 1.0-2.0 Transport HTTP berbasis libcurl (mendukung HTTP 2.0)
.NET Core 2.1 dan yang lebih baru System.Net.Http.SocketsHttpHandler

Pengguna juga dapat mengonfigurasi transport tertentu untuk HttpClient dengan memanggil konstruktor HttpClient yang menerima HttpMessageHandler.

.NET Framework & Mono

Secara default pada .NET Framework dan Mono, HttpWebRequest digunakan untuk mengirim permintaan ke server. Perilaku ini dapat dimodifikasi dengan menentukan pengelola yang berbeda dalam salah satu overload konstruktor dengan parameter HttpMessageHandler. Jika Anda memerlukan fitur seperti autentikasi atau caching, Anda dapat menggunakan WebRequestHandler untuk mengonfigurasi pengaturan, dan instansinya dapat diteruskan ke konstruktor. Handler yang dikembalikan dapat diteruskan ke overload konstruktor yang memiliki parameter HttpMessageHandler.

.NET Core

Dimulai dengan .NET Core 2.1, System.Net.Http.SocketsHttpHandler kelas alih-alih HttpClientHandler menyediakan implementasi yang digunakan oleh kelas jaringan HTTP tingkat lebih tinggi seperti HttpClient. Penggunaan SocketsHttpHandler menawarkan sejumlah keuntungan:

  • Peningkatan performa yang signifikan jika dibandingkan dengan implementasi sebelumnya.
  • Penghapusan dependensi platform, yang menyederhanakan penyebaran dan layanan. Misalnya, libcurl tidak lagi menjadi dependensi pada .NET Core untuk macOS dan .NET Core untuk Linux.
  • Perilaku konsisten di semua platform .NET.

Jika perubahan ini tidak diinginkan, pada Windows Anda dapat terus menggunakan WinHttpHandler dengan merujuk paket NuGet-nya dan meneruskannya ke konstruktor HttpClient secara manual.

Mengonfigurasi perilaku menggunakan opsi konfigurasi runtime

Aspek tertentu dari HttpClient perilaku dapat disesuaikan melalui opsi konfigurasi Runtime. Namun, perilaku sakelar ini berbeda melalui versi .NET. Misalnya, di .NET Core 2.1 - 3.1, Anda dapat mengonfigurasi apakah SocketsHttpHandler digunakan secara default, tetapi opsi tersebut tidak lagi tersedia mulai dari .NET 5.

Pengumpulan koneksi

HttpClient mengumpulkan koneksi HTTP jika memungkinkan dan menggunakannya untuk lebih dari satu permintaan. Ini dapat memiliki manfaat performa yang signifikan, terutama untuk permintaan HTTPS, karena jabat tangan koneksi hanya dilakukan sekali.

Properti kumpulan koneksi dapat dikonfigurasi pada HttpClientHandler atau SocketsHttpHandler yang diberikan saat proses pembuatan, termasuk MaxConnectionsPerServer, PooledConnectionIdleTimeout, dan PooledConnectionLifetime.

Membuang instans HttpClient menutup koneksi terbuka dan membatalkan permintaan yang tertunda.

Nota

Jika Anda secara bersamaan mengirim permintaan HTTP/1.1 ke server yang sama, koneksi baru dapat dibuat. Bahkan jika Anda menggunakan kembali instans HttpClient, jika tingkat permintaan tinggi, atau jika ada batasan firewall, hal ini dapat menghabiskan soket yang tersedia karena timer pembersihan TCP default. Untuk membatasi jumlah koneksi bersamaan, Anda dapat mengatur MaxConnectionsPerServer properti . Secara default, jumlah koneksi HTTP/1.1 bersamaan tidak terbatas.

Buffering dan umur permintaan

Secara bawaan, HttpClient metode (kecuali GetStreamAsync) membuffer respons dari server, membaca semua isi respons ke dalam memori sebelum mengembalikan hasil yang bersifat asinkron. Permintaan tersebut akan berlanjut sampai salah satu hal berikut terjadi:

Anda dapat mengubah perilaku buffering untuk setiap permintaan dengan menggunakan parameter HttpCompletionOption yang tersedia pada beberapa metode overload. Argumen ini dapat digunakan untuk menentukan apakah Task<TResult> harus dianggap selesai setelah hanya membaca header respons, atau setelah membaca dan buffer konten respons.

Jika aplikasi Anda yang menggunakan HttpClient dan kelas terkait di System.Net.Http namespace ingin mengunduh data dalam jumlah besar (50 megabyte atau lebih), aplikasi harus melakukan streaming unduhan tersebut dan tidak menggunakan buffering default. Jika Anda menggunakan buffering default, penggunaan memori klien akan menjadi sangat besar, berpotensi mengakibatkan performa yang berkurang secara substansial.

Keamanan Benang

Metode berikut aman untuk utas:

Proksi

Secara default, HttpClient membaca konfigurasi proksi dari variabel lingkungan atau pengaturan pengguna/sistem, tergantung pada platform. Anda dapat mengubah perilaku ini dengan meneruskan WebProxy atau IWebProxy ke, dalam urutan prioritas:

  • Properti Proxy pada HttpClientHandler yang diteruskan pada saat HttpClient pembangunan
  • Properti statis DefaultProxy (mempengaruhi semua instans)

Anda dapat menonaktifkan proksi menggunakan UseProxy. Konfigurasi default untuk pengguna Windows adalah mencoba dan mendeteksi proksi menggunakan penemuan jaringan, yang bisa lambat. Untuk aplikasi throughput tinggi di mana diketahui bahwa proksi tidak diperlukan, Anda harus menonaktifkan proksi.

Pengaturan proksi (seperti Credentials) harus diubah hanya sebelum permintaan pertama dibuat menggunakan HttpClient. Perubahan yang dilakukan setelah menggunakan HttpClient untuk pertama kalinya mungkin tidak tercermin dalam permintaan berikutnya.

Istirahat

Anda dapat menggunakan Timeout untuk mengatur batas waktu default untuk semua permintaan HTTP dari HttpClient instans. Batas waktu hanya berlaku untuk metode xxxAsync yang menyebabkan permintaan/respons dimulai. Jika batas waktu tercapai, Task<TResult> untuk permintaan tersebut dibatalkan.

Anda dapat mengatur beberapa batas waktu tambahan jika Anda meneruskan instans SocketsHttpHandler ketika Anda membuat objek HttpClient

Harta benda Deskripsi
ConnectTimeout Menentukan batas waktu yang digunakan saat permintaan memerlukan koneksi TCP baru untuk dibuat. Jika batas waktu habis terjadi, permohonan Task<TResult> dibatalkan.
PooledConnectionLifetime Menentukan batas waktu yang akan digunakan untuk setiap koneksi di kumpulan koneksi. Jika koneksi diam, koneksi segera ditutup; jika tidak, koneksi ditutup di akhir permintaan saat ini.
PooledConnectionIdleTimeout Jika koneksi di kumpulan koneksi menganggur selama waktu ini, koneksi tersebut akan ditutup.
Expect100ContinueTimeout Jika permintaan memiliki header "Expect: 100-continue", pengiriman konten akan ditunda hingga waktu tunggu berakhir atau hingga respons "100-continue" diterima.

HttpClient hanya menyelesaikan entri DNS saat koneksi dibuat. Ini tidak melacak waktu hidup (TTL) yang ditentukan oleh server DNS. Jika entri DNS berubah secara teratur, yang dapat terjadi dalam beberapa skenario kontainer, Anda dapat menggunakan PooledConnectionLifetime untuk membatasi masa pakai koneksi sehingga pencarian DNS diperlukan saat mengganti koneksi.