Pemahaman Saya tentang Polling HTTP, Polling Panjang, Streaming HTTP, dan WebSockets

123

Saya telah membaca banyak posting di SO dan web mengenai kata kunci dalam judul pertanyaan saya dan belajar banyak dari mereka. Beberapa pertanyaan yang saya baca terkait dengan tantangan implementasi tertentu sementara yang lain berfokus pada konsep umum. Saya hanya ingin memastikan bahwa saya memahami semua konsep dan alasan mengapa teknologi X ditemukan di atas teknologi Y dan seterusnya. Jadi begini:

Http Polling: Pada dasarnya AJAX, menggunakan XmlHttpRequest.

Http Long Polling: AJAX tetapi server menahan respons kecuali server memiliki pembaruan, segera setelah server memiliki pembaruan, ia mengirimkannya dan kemudian klien dapat mengirim permintaan lain. Kerugiannya adalah data header tambahan yang perlu dikirim bolak-balik menyebabkan overhead tambahan.

Streaming Http: Mirip dengan polling panjang tetapi server merespons dengan header dengan "Transfer Encoding: chunked" dan karenanya kami tidak perlu memulai permintaan baru setiap kali server mengirimkan beberapa data (dan karenanya menghemat overhead header tambahan). Kekurangannya di sini adalah kita harus "memahami" dan mencari tahu struktur data untuk membedakan antara beberapa potongan yang dikirim oleh server.

Java Applet, Flash, Silverlight: Mereka menyediakan kemampuan untuk terhubung ke server soket melalui tcp / ip tetapi karena mereka adalah plugin, pengembang tidak ingin bergantung padanya.

WebSockets: mereka adalah API baru yang mencoba mengatasi kekurangan metode di atas dengan cara berikut:

  • Satu-satunya keuntungan WebSockets dibandingkan plugin seperti Java Applets, Flash atau Silverlight adalah bahwa WebSockets secara native dibangun ke dalam browser dan tidak bergantung pada plugin.
  • Satu-satunya keuntungan WebSockets dibandingkan streaming http adalah Anda tidak perlu berusaha "memahami" dan mengurai data yang diterima.
  • Satu-satunya keuntungan WebSockets dibandingkan Long Polling adalah penghapusan ukuran header ekstra & pembukaan dan penutupan koneksi soket untuk permintaan.

Apakah ada perbedaan signifikan lainnya yang saya lewatkan? Saya minta maaf jika saya menanyakan kembali atau menggabungkan banyak pertanyaan yang sudah ada di SO menjadi satu pertanyaan, tapi saya hanya ingin memahami semua info yang ada di SO dan web mengenai konsep ini.

Terima kasih!

Orang Perangkat Lunak
sumber
4
Peristiwa Terkirim Server mungkin juga layak untuk dilihat saat Anda tidak memerlukan komunikasi dua arah.
leggetter
1
Ini adalah pertanyaan yang sangat berguna. Saya pikir ini akan berpotensi lebih berguna jika ada satu jawaban yang dapat disumbangkan oleh banyak penulis.
leggetter
@leggetter Terima kasih Phil, terima kasih atas tip terkait acara server yang dikirim. Saya tertarik mempelajari tentang skenario komunikasi dua arah. Terima kasih.
Software Guy
1
Dengan HTTP Streaming dan Long-Polling, Anda memerlukan koneksi kedua untuk komunikasi dua arah. Satu koneksi tahan lama untuk server -> komunikasi 'push' klien dan koneksi jangka pendek kedua untuk klien -> komunikasi server. Koneksi kedua ini digunakan untuk melakukan hal-hal seperti mengatur dan mengubah langganan ke data. Jadi, EventSource dapat digunakan dalam solusi dua arah dan sebenarnya adalah solusi standar yang lahir dari HTTP Streaming dan Long-Polling.
leggetter
1
Anda mungkin juga ingin memeriksa klasifikasi teknik yang saya tulis ini: stackoverflow.com/questions/12078550/…
Alessandro Alinone

Jawaban:

92

Ada lebih banyak perbedaan daripada yang telah Anda identifikasi.

Dupleks / arah:

  • Uni-directional: polling HTTP, polling panjang, streaming.
  • Bi-direcitonal: WebSockets, jaringan plugin

Untuk meningkatkan latensi (perkiraan):

  • WebSockets
  • Jaringan plugin
  • Streaming HTTP
  • Jajak pendapat panjang HTTP
  • Polling HTTP

CORS (dukungan lintas sumber):

  • WebSockets: ya
  • Jaringan plugin: Flash melalui permintaan kebijakan (tidak yakin tentang yang lain)
  • HTTP * (beberapa dukungan terbaru)

Data biner asli (array yang diketik, blob):

  • WebSockets: ya
  • Jaringan plugin: bukan dengan Flash (memerlukan pengkodean URL di ExternalInterface)
  • HTTP *: proposal terbaru untuk mengaktifkan dukungan jenis biner

Bandwidth dalam mengurangi efisiensi:

  • Jaringan plugin: Soket flash mentah kecuali untuk permintaan kebijakan awal
  • WebSockets: jabat tangan pengaturan koneksi dan beberapa byte per frame
  • Streaming HTTP (penggunaan kembali koneksi server)
  • Jajak pendapat panjang HTTP: koneksi untuk setiap pesan
  • Polling HTTP: koneksi untuk setiap pesan + tidak ada pesan data

Dukungan perangkat seluler:

  • WebSocket: iOS 4.2 dan yang lebih baru. Beberapa Android melalui emulasi Flash atau menggunakan Firefox untuk Android atau Google Chrome untuk Android yang keduanya menyediakan dukungan WebSocket asli.
  • Jaringan plugin: beberapa Android. Tidak di iOS
  • HTTP *: sebagian besar ya

Kompleksitas penggunaan Javascript (dari yang paling sederhana hingga yang paling rumit). Ukuran kompleksitas memang agak subjektif.

  • WebSockets
  • Polling HTTP
  • Jaringan plugin
  • Polling panjang HTTP, streaming

Perhatikan juga bahwa ada proposal W3C untuk standarisasi streaming HTTP yang disebut Server-Sent Events . Saat ini cukup awal dalam evolusinya dan dirancang untuk menyediakan API Javascript standar dengan kesederhanaan yang sebanding dengan WebSockets.

kanaka
sumber
1
Terima kasih banyak atas balasan bagus Kanaka. Bisakah Anda memberi tahu saya mengapa / bagaimana streaming http memiliki latensi yang lebih tinggi daripada websockets? mungkin dengan contoh sederhana? Terima kasih banyak.
Software Guy
2
@Perangkat lunak. Banyak alasan. Pada browser terbaru, Anda bisa menggunakan penanganan kejadian onprogress XMLHTTPRequest untuk diberitahu tentang data. Tapi spek mengatakan 50ms adalah interval notifikasi terkecil. Jika tidak, Anda harus mengumpulkan data respons. Selain itu, klien mengirim sambungan HTTP baru dan secara signifikan meningkatkan latensi bolak-balik. Selain itu, banyak server web memutuskan koneksi HTTP setelah 30 detik atau lebih yang berarti Anda sering harus terus membangun kembali koneksi server push. Saya telah melihat latensi bolak-balik WebSocket 5-10ms di jaringan lokal. Latensi streaming HTTP kemungkinan akan menjadi 50ms +.
kanaka
Terima kasih banyak atas balasan mendetailnya :)
Software Guy
1
@ Leggetter Terima kasih Phil, maksud Anda mengirim data dari klien ke server melalui streaming http akan menyebabkan overhead? apakah mengirim data ke server dapat dilakukan melalui streaming http tanpa membuka koneksi baru? Terima kasih.
Software Guy
1
@Nathan terdengar seperti proyek tesis gelar master yang bagus! Tentu saja, polling akan membuat sistem lebih sibuk daripada model yang digerakkan oleh peristiwa, tetapi penghematan daya seperti apa yang mungkin membutuhkan pengujian empiris yang cukup ekstensif pada skala yang berbeda.
kanaka
13

Beberapa jawaban bagus dari orang lain yang mencakup banyak hal. Ini sedikit tambahan.

Satu-satunya keuntungan WebSockets dibandingkan plugin seperti Java Applets, Flash atau Silverlight adalah bahwa WebSockets secara native dibangun ke dalam browser dan tidak bergantung pada plugin.

Jika dengan ini Anda bermaksud bahwa Anda dapat menggunakan Java Applet, Flash, atau Silverlight untuk membuat sambungan soket, maka ya, itu mungkin. Namun Anda tidak melihatnya diterapkan di dunia nyata terlalu sering karena batasannya.

Misalnya, perantara dapat dan melakukan penutupan lalu lintas tersebut. Standar WebSocket dirancang agar kompatibel dengan infrastruktur HTTP yang ada dan oleh karena itu jauh lebih kecil kemungkinannya untuk diganggu oleh perantara seperti firewall dan proxy.

Selain itu, WebSocket dapat menggunakan port 80 dan 443 tanpa memerlukan port khusus, sekali lagi berkat desain protokol yang kompatibel dengan infrastruktur HTTP yang ada.

Alternatif soket tersebut (Java, Flash, dan Silverlight) sulit digunakan dengan aman dalam arsitektur lintas sumber. Jadi orang yang sering mencoba menggunakannya lintas sumber akan mentolerir ketidakamanan daripada berusaha melakukannya dengan aman.

Mereka juga dapat meminta port "non-standar" tambahan untuk dibuka (sesuatu yang tidak ingin dilakukan oleh administrator) atau file kebijakan yang perlu dikelola.

Singkatnya, menggunakan Java, Flash, atau Silverlight untuk konektivitas soket cukup bermasalah sehingga Anda tidak terlalu sering melihatnya diterapkan dalam arsitektur yang serius. Flash dan Java telah memiliki kemampuan ini setidaknya selama 10 tahun, namun itu tidak lazim.

Standar WebSocket dapat dimulai dengan pendekatan baru, dengan mempertimbangkan batasan tersebut, dan mudah-mudahan telah belajar beberapa pelajaran darinya.

Beberapa implementasi WebSocket menggunakan Flash (atau mungkin Silverlight dan / atau Java) sebagai fallbacknya saat konektivitas WebSocket tidak dapat dibuat (seperti saat berjalan di browser lama atau saat perantara mengganggu).

Meskipun beberapa jenis strategi fallback untuk situasi tersebut adalah cerdas, bahkan perlu, kebanyakan dari mereka yang menggunakan Flash dkk akan mengalami kekurangan yang dijelaskan di atas. Tidak harus seperti itu - ada beberapa solusi untuk mencapai koneksi berkemampuan lintas sumber yang aman menggunakan Flash, Silverlight, dll - tetapi sebagian besar implementasi tidak akan melakukannya karena itu tidak mudah.

Misalnya, jika Anda mengandalkan WebSocket untuk koneksi lintas sumber, itu akan berfungsi dengan baik. Tetapi jika Anda kemudian menjalankan di browser lama atau firewall / proxy mengganggu dan mengandalkan Flash, katakanlah, sebagai fallback Anda, Anda akan kesulitan melakukan koneksi lintas-sumber yang sama. Kecuali Anda tidak peduli dengan keamanan, tentu saja.

Itu berarti sulit untuk memiliki satu arsitektur terpadu yang berfungsi untuk koneksi native dan non-native, kecuali jika Anda siap untuk melakukan sedikit pekerjaan atau menggunakan kerangka kerja yang telah melakukannya dengan baik. Dalam arsitektur yang ideal, Anda tidak akan memperhatikan apakah koneksi itu asli atau tidak; pengaturan keamanan Anda akan berfungsi dalam kedua kasus; pengaturan pengelompokan Anda akan tetap berfungsi; perencanaan kapasitas Anda akan tetap berlaku; dan seterusnya.

Satu-satunya keuntungan WebSockets dibandingkan streaming http adalah Anda tidak perlu berusaha "memahami" dan mengurai data yang diterima.

Ini tidak sesederhana membuka aliran HTTP dan duduk santai saat data Anda mengalir selama beberapa menit, jam, atau lebih lama. Klien yang berbeda berperilaku berbeda dan Anda harus mengelolanya. Misalnya beberapa klien akan menyangga data dan tidak merilisnya ke aplikasi sampai beberapa ambang batas terpenuhi. Lebih buruk lagi, beberapa tidak akan meneruskan data ke aplikasi sampai koneksi ditutup.

Jadi jika Anda mengirim banyak pesan ke klien, mungkin aplikasi klien tidak akan menerima data sampai 50 data senilai data telah diterima, misalnya. Itu tidak terlalu real-time.

Meskipun streaming HTTP bisa menjadi alternatif yang layak saat WebSocket tidak tersedia, ini bukanlah obat mujarab. Diperlukan pemahaman yang baik untuk bekerja dengan cara yang kuat di tanah tandus Web dalam kondisi dunia nyata.

Apakah ada perbedaan signifikan lainnya yang saya lewatkan?

Ada satu hal lain yang belum disebutkan, jadi saya akan membahasnya.

Protokol WebSocket dirancang untuk menjadi lapisan transport untuk protokol tingkat yang lebih tinggi. Meskipun Anda dapat mengirim pesan JSON atau yang tidak secara langsung melalui koneksi WebSocket, itu juga dapat membawa protokol standar atau kustom.

Misalnya, Anda dapat melakukan AMQP atau XMPP melalui WebSocket, seperti yang telah dilakukan orang. Jadi klien dapat menerima pesan dari broker AMQP seolah-olah terhubung langsung ke broker itu sendiri (dan dalam beberapa kasus memang demikian).

Atau jika Anda memiliki server yang sudah ada dengan beberapa protokol khusus, Anda dapat memindahkannya melalui WebSocket, sehingga memperluas server back-end tersebut ke Web. Seringkali aplikasi yang sudah ada yang telah dikunci di perusahaan dapat memperluas jangkauannya menggunakan WebSocket, tanpa harus mengubah infrastruktur back-end apa pun.

(Secara alami, Anda ingin dapat melakukan semua itu dengan aman, jadi tanyakan kepada vendor atau penyedia WebSocket.)

Beberapa orang menyebut WebSocket sebagai TCP untuk Web. Karena sama seperti TCP mengangkut protokol tingkat yang lebih tinggi, begitu pula WebSocket, tetapi dengan cara yang kompatibel dengan infrastruktur Web.

Jadi, meskipun mengirim pesan JSON (atau apa pun) secara langsung melalui WebSocket selalu memungkinkan, Anda juga harus mempertimbangkan protokol yang ada. Karena untuk banyak hal yang ingin Anda lakukan, mungkin ada protokol yang sudah dipikirkan untuk melakukannya.

Saya minta maaf jika saya menanyakan kembali atau menggabungkan banyak pertanyaan yang sudah ada di SO menjadi satu pertanyaan, tapi saya hanya ingin memahami semua info yang ada di SO dan web mengenai konsep ini.

Ini adalah pertanyaan yang bagus, dan semua jawabannya sangat informatif!

Robin Zimmermann
sumber
Terima kasih banyak Robin untuk bantuan dan info yang luar biasa. Jika saya boleh menanyakan satu hal tambahan: Saya menemukan sebuah artikel di suatu tempat yang mengatakan bahwa streaming http juga dapat di-cache oleh proxy sementara websockets tidak. apa artinya?
Software Guy
Karena StackOverflow membatasi ukuran dalam tanggapan komentar, saya memberikan jawaban saya di bawah ini: stackoverflow.com/questions/12555043/…
Robin Zimmermann
@RobinZimmermann, jawaban Anda adalah favorit saya. 1 untuk jawaban mendetail yang sangat bagus.
securecurve
10

Jika saya boleh bertanya satu hal tambahan: Saya menemukan sebuah artikel di suatu tempat yang mengatakan bahwa streaming http juga dapat di-cache oleh proxy sementara websockets tidak. apa artinya?

(StackOverflow membatasi ukuran tanggapan komentar, jadi saya harus menjawab di sini daripada sebaris.)

Itu poin yang bagus. Untuk memahami ini, pikirkan tentang skenario HTTP tradisional ... Bayangkan sebuah browser membuka halaman web, jadi ia meminta http://example.com , katakanlah. Server merespons dengan HTTP yang berisi HTML untuk halaman tersebut. Kemudian browser melihat bahwa ada sumber daya di halaman tersebut, jadi browser mulai meminta file CSS, file JavaScript, dan gambar tentunya. Mereka semua adalah file statis yang akan sama untuk semua klien yang memintanya.

Beberapa proxy akan menyimpan sumber daya statis sehingga permintaan berikutnya dari klien lain bisa mendapatkan sumber daya statis tersebut dari proxy, daripada harus kembali ke server web pusat untuk mendapatkannya. Ini adalah caching, dan ini merupakan strategi yang bagus untuk memindahkan permintaan dan pemrosesan dari layanan pusat Anda.

Jadi klien # 1 meminta http://example.com/images/logo.gif , misalnya. Permintaan itu melewati proxy sampai ke server web pusat, yang menyajikan logo.gif. Saat logo.gif melewati proxy, proxy akan menyimpan gambar itu dan mengaitkannya dengan alamat http://example.com/images/logo.gif .

Ketika klien # 2 datang dan juga meminta http://example.com/images/logo.gif , proxy dapat mengembalikan gambar dan tidak perlu komunikasi kembali ke server web di tengah. Ini memberikan respons yang lebih cepat kepada pengguna akhir, yang selalu bagus, tetapi juga berarti lebih sedikit beban di tengah. Itu bisa berarti mengurangi biaya perangkat keras, mengurangi biaya jaringan, dll. Jadi itu hal yang baik.

Masalah muncul saat logo.gif diperbarui di server web. Proksi akan terus menampilkan gambar lama tanpa menyadari bahwa ada gambar baru. Hal ini menyebabkan semua hal di sekitar kedaluwarsa sehingga proxy hanya akan menyimpan gambar dalam cache untuk waktu yang singkat sebelum "kedaluwarsa" dan permintaan berikutnya melewati proxy ke server web, yang kemudian menyegarkan cache proxy. Ada juga solusi yang lebih canggih di mana server pusat dapat mendorong ke cache yang diketahui, dan seterusnya, dan semuanya bisa menjadi sangat canggih.

Bagaimana hal ini terkait dengan pertanyaan Anda?

Anda bertanya tentang streaming HTTP di mana server mengalirkan HTTP ke klien. Tetapi streaming HTTP sama seperti HTTP biasa kecuali Anda tidak berhenti mengirim data. Jika server web menyajikan gambar, HTTP dikirim ke klien yang pada akhirnya berakhir: Anda telah mengirim seluruh gambar. Dan jika Anda ingin mengirim data, itu persis sama, tetapi server hanya mengirim untuk waktu yang sangat lama (seperti gambar yang sangat besar, katakanlah) atau bahkan tidak pernah selesai.

Dari sudut pandang proxy, ini tidak dapat membedakan antara HTTP untuk sumber daya statis seperti gambar, atau data dari streaming HTTP. Dalam kedua kasus tersebut, klien membuat permintaan ke server. Proksi mengingat permintaan itu dan juga tanggapannya. Saat permintaan itu masuk lagi, proxy menyajikan respons yang sama.

Jadi, jika klien Anda membuat permintaan untuk harga saham, katakanlah, dan mendapat respons, maka klien berikutnya dapat membuat permintaan yang sama dan mendapatkan data yang disimpan dalam cache. Mungkin bukan yang Anda inginkan! Jika Anda meminta harga saham, Anda menginginkan data terbaru, bukan?

Jadi itu masalah.

Ada trik dan solusi untuk menangani masalah seperti itu, memang benar. Jelas Anda bisa mendapatkan streaming HTTP untuk bekerja karena itu digunakan hari ini. Semuanya transparan bagi pengguna akhir, tetapi orang yang mengembangkan dan memelihara arsitektur tersebut harus melewati rintangan dan membayar harga. Ini menghasilkan arsitektur yang terlalu rumit, yang berarti lebih banyak perawatan, lebih banyak perangkat keras, lebih banyak kompleksitas, lebih banyak biaya. Ini juga berarti pengembang sering kali harus peduli tentang sesuatu yang seharusnya tidak mereka lakukan ketika mereka seharusnya hanya berfokus pada aplikasi, GUI, dan logika bisnis - mereka tidak perlu khawatir tentang komunikasi yang mendasarinya.

Robin Zimmermann
sumber
1
detail yang sangat baik Robin, terima kasih banyak! Saya sangat menghargai tanggapan menyeluruh Anda. Saya telah belajar banyak dari semua orang hebat di sini! :)
Software Guy
4

HTTP membatasi jumlah koneksi yang dapat dimiliki klien dengan server menjadi 2 (meskipun hal ini dapat dikurangi dengan menggunakan subdomain) dan IE telah dikenal untuk menegakkannya dengan penuh semangat. Firefox dan Chrome mengizinkan lebih banyak (walaupun saya tidak ingat persis berapa banyak). Ini mungkin tidak tampak seperti masalah besar tetapi jika Anda menggunakan 1 koneksi terus-menerus untuk pembaruan waktu nyata, semua permintaan lainnya harus mengalami hambatan melalui koneksi HTTP lainnya. Dan ada masalah memiliki lebih banyak koneksi terbuka dari klien membuat lebih banyak beban di server.

WebSockets adalah protokol berbasis TCP dan dengan demikian tidak mengalami batas koneksi tingkat HTTP ini (tetapi, tentu saja, dukungan browser tidak seragam).

Jus
sumber
terima kasih jusnya, jadi selain masalah beberapa koneksi simultan seperti yang disorot oleh Anda, apakah asumsi saya lainnya tentang websockets benar?
Software Guy