Mengapa menggunakan AJAX saat WebSockets tersedia?

203

Saya telah menggunakan WebSockets untuk sementara waktu sekarang, saya telah memilih untuk membuat alat manajemen proyek Agile untuk proyek tahun terakhir saya di Universitas menggunakan Node server dan WebSockets. Saya menemukan menggunakan WebSockets memberikan 624% peningkatan jumlah permintaan per detik yang bisa diproses oleh aplikasi saya.

Namun sejak memulai proyek saya sudah membaca celah keamanan, dan beberapa browser memilih untuk menonaktifkan WebSockets secara default ..

Ini mengarahkan saya ke pertanyaan:

Mengapa menggunakan AJAX ketika WebSockets tampaknya melakukan pekerjaan yang hebat untuk menurunkan latensi dan overhead sumber daya, adakah yang lebih baik dari AJAX daripada WebSockets?

Mendongkrak
sumber
2
Berikut daftar mesin yang mendukung soket web. en.wikipedia.org/wiki/…
Dante

Jawaban:

209

WebSockets tidak dimaksudkan untuk menggantikan AJAX dan bahkan bukan pengganti Comet / jajak pendapat panjang (meskipun ada banyak kasus di mana ini masuk akal).

Tujuan WebSockets adalah untuk menyediakan koneksi latensi rendah, dua arah, dupleks penuh, dan berjalan lama antara browser dan server. WebSockets membuka domain aplikasi baru ke aplikasi browser yang sebenarnya tidak mungkin menggunakan HTTP dan AJAX (game interaktif, stream media dinamis, menjembatani protokol jaringan yang ada, dll.).

Namun, tentu saja ada tumpang tindih antara WebSockets dan AJAX / Comet. Sebagai contoh, ketika browser ingin diberitahu tentang peristiwa server (yaitu push) maka teknik Comet dan WebSockets tentu saja keduanya merupakan opsi yang layak. Jika aplikasi Anda membutuhkan acara push latensi rendah maka ini akan menjadi faktor yang mendukung WebSockets. Di sisi lain, jika Anda perlu hidup berdampingan dengan kerangka kerja yang ada dan teknologi yang digunakan (OAuth, RESTful APIs, proxy, load balancers) maka ini akan menjadi faktor yang mendukung teknik Komet (untuk saat ini).

Jika Anda tidak memerlukan manfaat spesifik yang disediakan WebSockets, maka mungkin ide yang lebih baik untuk tetap menggunakan teknik yang ada seperti AJAX dan Comet karena ini memungkinkan Anda untuk menggunakan kembali dan mengintegrasikan dengan ekosistem besar alat, teknologi, mekanisme keamanan yang ada , basis pengetahuan (yaitu jauh lebih banyak orang di stackoverflow yang tahu HTTP / Ajax / Comet daripada WebSockets), dll.

Di sisi lain, jika Anda membuat aplikasi baru yang tidak berfungsi dengan baik dalam latensi dan kendala koneksi HTTP / Ajax / Comet, maka pertimbangkan untuk menggunakan WebSockets.

Juga, beberapa jawaban menunjukkan bahwa salah satu kelemahan WebSockets adalah dukungan server dan browser yang terbatas / campuran. Biarkan saya sedikit meredakannya. Sementara iOS (iPhone, iPad) masih mendukung protokol yang lebih lama (Hixie), kebanyakan server WebSockets mendukung Hixie dan versi HyBi / IETF 6455 . Sebagian besar platform lain (jika belum memiliki dukungan bawaan) dapat memperoleh dukungan WebSockets melalui web-socket-js (polyfill berbasis Flash). Ini mencakup sebagian besar pengguna web. Juga, jika Anda menggunakan Node untuk backend server, maka pertimbangkan untuk menggunakan Socket.IO yang menyertakan web-socket-js sebagai cadangan dan jika bahkan itu tidak tersedia (atau dinonaktifkan) maka ia akan kembali menggunakan teknik Komet apa pun. tersedia untuk browser yang diberikan.

Pembaruan : iOS 6 sekarang mendukung standar HyBi / IETF 6455 saat ini.

kanaka
sumber
37
Dan sekarang pada awal tahun 2014, WebSockets praktis standar (RFC 6455) dan hanya Opera mini yang tidak mendukungnya.
Dirk Bester
4
Benar, Opera Mini tidak mendukungnya tetapi yang lebih memalukan adalah kurangnya dukungan dari peramban Android yang membuatnya sedikit lebih rumit untuk digunakan dengan aplikasi berbasis tampilan web (Cordova PhoneGap)
Miles M.
2
@kanaka, Jika keduanya melakukan file besar dengan baik, mengapa tidak mengirim semuanya melalui websockets saja? Mengapa repot-repot membuat halaman / data saat semuanya dapat dikirim melalui WebSockets? (Mari kita asumsikan sudah tahun 2020 dan semua browser memiliki dukungan untuk WebSockets)
Pacerier
3
@Pacerier jawaban yang lengkap akan panjang, tetapi pada dasarnya bermuara pada kenyataan bahwa Anda mencoba untuk mengimplementasikan kembali hal-hal yang sudah dilakukan browser dengan baik (caching, keamanan, paralelisme, penanganan kesalahan, dll). Mengenai kinerja, meskipun dari awal kecepatan transfer file besar mentah akan serupa, browser telah bertahun-tahun untuk secara halus menyetel caching konten web (banyak yang berlaku untuk permintaan AJAX) sehingga dalam praktiknya, beralih dari AJAX ke WebSockets tidak mungkin memberikan banyak manfaat untuk fungsionalitas yang ada. Tetapi untuk komunikasi dua arah latensi rendah, ini adalah kemenangan besar.
kanaka
5
Saya minta maaf tetapi bagi saya itu tidak menjawab pertanyaan. Pada dasarnya hanya mengatakan bahwa mereka tidak dimaksudkan untuk saling menggantikan dan WS tidak sepenuhnya didukung (sekarang). Itu tidak menjawab mengapa Anda lebih suka AJAX daripada websocket? Mari kita ambil Discord sebagai contoh. Discord menggunakan WS untuk mendorong pesan dan acara dari server ke klien, sementara itu menggunakan permintaan HTTP dari klien ke server (mengirim pesan, meminta data, dll.). Saya datang ke pertanyaan ini untuk benar-benar mendapatkan jawaban mengapa Anda melakukan itu. Apakah ada semacam alasan teknis mengapa Anda akan menempatkan AJAX di atas koneksi WS terbuka?
Charlotte Dunois
63

Maju cepat hingga Desember 2017, Websockets didukung oleh (praktis) setiap browser dan penggunaannya sangat umum.

Namun, ini tidak berarti bahwa Websockets berhasil menggantikan AJAX, setidaknya tidak sepenuhnya, terutama karena adaptasi HTTP / 2 sedang meningkat.

Jawaban singkatnya adalah bahwa AJAX masih bagus untuk sebagian besar aplikasi REST, bahkan ketika menggunakan Websockets. Tapi tuhan ada di perinciannya, jadi ...:

AJAX untuk pemungutan suara?

Penggunaan AJAX untuk pemungutan suara (atau pemungutan suara panjang) sedang sekarat (dan seharusnya), tetapi masih digunakan untuk dua alasan yang baik (terutama untuk aplikasi web yang lebih kecil):

  1. Bagi banyak pengembang, AJAX lebih mudah untuk dikodekan, terutama dalam hal pengkodean dan desain backend.

  2. Dengan HTTP / 2, biaya tertinggi yang terkait dengan AJAX (pembuatan koneksi baru) dihilangkan, memungkinkan panggilan AJAX menjadi sangat berkinerja, terutama untuk memposting dan mengunggah data.

Namun, dorongan Websocket jauh lebih unggul daripada AJAX (tidak perlu mengautentikasi ulang atau mengirim ulang tajuk, tidak perlu bolak-balik "tidak ada data", dll.). Ini dibahas beberapa kali.

AJAX untuk REST?

Penggunaan yang lebih baik untuk AJAX adalah panggilan API REST. Penggunaan ini menyederhanakan basis kode dan mencegah koneksi Websocket dari pemblokiran (terutama pada unggahan data berukuran sedang).

Ada sejumlah alasan kuat untuk memilih AJAX untuk panggilan API dan unggahan data:

  1. API AJAX secara praktis dirancang untuk panggilan REST API dan ini sangat cocok.

  2. Panggilan dan unggahan REST menggunakan AJAX secara signifikan lebih mudah untuk dikodekan, baik pada klien dan backend.

  3. Dengan meningkatnya payload data, koneksi Websocket mungkin diblokir kecuali logika fragmentasi / multiplexing pesan dikodekan.

    Jika suatu pengunggahan dilakukan dalam satu sendpanggilan Websocket , ia dapat memblokir aliran Websocket sampai pengunggahan selesai. Ini akan mengurangi kinerja, terutama pada klien yang lebih lambat.

Desain umum menggunakan pesan bidi kecil yang ditransfer melalui Websockets sementara REST dan unggahan data (klien ke server) memanfaatkan kemudahan penggunaan AJAX untuk mencegah pemblokiran Websocket.

Namun, pada proyek yang lebih besar, fleksibilitas yang ditawarkan oleh Websockets dan keseimbangan antara kompleksitas kode dan manajemen sumber daya akan memberi keseimbangan pada Websockets.

Misalnya, unggahan berbasis Websocket dapat menawarkan kemampuan untuk melanjutkan unggahan besar setelah koneksi terputus dan dibangun kembali (ingat bahwa film 5GB yang ingin Anda unggah?).

Dengan mengkode logika fragmentasi unggahan, mudah untuk melanjutkan kembali unggahan yang terputus (bagian yang sulit adalah mengkode hal tersebut).

Bagaimana dengan push HTTP / 2?

Saya mungkin harus menambahkan bahwa fitur push HTTP / 2 tidak (dan mungkin tidak bisa) menggantikan Websockets.

Ini sudah dibahas di sini sebelumnya, tetapi cukup untuk menyebutkan bahwa satu koneksi HTTP / 2 melayani seluruh browser (semua tab / windows), sehingga data yang didorong oleh HTTP / 2 tidak tahu di mana tab / jendela itu milik, menghilangkan kapasitasnya untuk menggantikan kemampuan Websocket untuk mendorong data secara langsung ke tab / jendela browser tertentu.

Meskipun Websockets sangat bagus untuk komunikasi data dua arah yang kecil, AJAX masih membawa sejumlah keunggulan - terutama ketika mempertimbangkan muatan yang lebih besar (unggah, dll.).

Dan keamanan?

Secara umum, semakin banyak kepercayaan dan kontrol yang ditawarkan kepada seorang programmer, semakin kuat alatnya ... dan semakin banyak masalah keamanan yang muncul.

AJAX secara alami akan berada di atas angin, karena keamanannya dibangun pada kode browser (yang terkadang dipertanyakan, tetapi masih ada).

Di sisi lain, panggilan AJAX lebih rentan terhadap serangan "man in the middle", sementara masalah keamanan Websockets biasanya bug dalam kode aplikasi yang memperkenalkan cacat keamanan (biasanya logika otentikasi backend adalah tempat Anda akan menemukan ini).

Secara pribadi saya tidak menemukan ini sebagai perbedaan besar, jika sesuatu yang saya pikir Websockets sedikit lebih baik, terutama ketika Anda tahu apa yang Anda lakukan.

Pendapatku yang Rendah Hati

IMHO, saya akan menggunakan Websockets untuk semuanya kecuali panggilan API REST. Upload data besar saya akan memecah dan mengirim melalui Websockets jika memungkinkan.

Polling, IMHO, harus dilarang, biaya lalu lintas jaringan mengerikan dan dorongan Websocket cukup mudah untuk dikelola bahkan untuk pengembang baru.

Mister
sumber
2
Kesalahan tata bahasa kecil 'jika ada sesuatu yang saya ...' pikirkan 😀
spottedmahn
2
@spottedmahn - Terima kasih! Saya kira itulah yang terjadi, saya menggunakan editor kode saya untuk menyusun teks 🙃
Myst
1
Permintaan maaf, saya absen ketika hadiah berakhir. Perencanaan yang buruk di pihak saya. Saya telah menetapkan hadiah lain yang akan saya berikan kepada Anda setelah 23 jam berakhir.
Duncan Jones
@Mrs terima kasih atas penjelasan yang bagus ini. Apa yang Anda inginkan untuk notifikasi langsung seperti fb / stackoverflow? Saya merancang layanan web RestFull untuk aplikasi web saya, tetapi sangat bingung apa yang harus saya gunakan untuk fitur notifikasi? AJAX atau WebSockets?
TheCoder
Pemberitahuan @puspen (IMHO) sangat cocok untuk Websockets. Ada banyak keputusan yang harus diambil ketika Anda mendesain logika koneksi ulang dan antrian notifikasi offline, tetapi notifikasi yang sebenarnya mudah dikodekan dan ditampilkan dengan websockets.
Myst
18

Selain masalah dengan browser lama (termasuk IE9, karena WebSockets akan didukung mulai dari IE10), masih ada masalah besar dengan perantara jaringan yang belum mendukung WebSockets, termasuk proxy transparan, proxy terbalik, dan load balancers. Ada beberapa operator seluler yang sepenuhnya memblokir lalu lintas WebSocket (yaitu, setelah perintah HTTP UPGRADE).

Dengan berlalunya waktu, WebSockets akan semakin didukung, tetapi sementara itu Anda harus selalu memiliki metode cadangan berbasis HTTP untuk mengirim data ke browser.

Alessandro Alinone
sumber
Untungnya sebagian besar kerangka kerja WebSocket mendukung kata fallback, termasuk menggunakan Flash untuk soket. Socketn.IO dan SignalR keduanya kerangka kerja yang layak ... meskipun Anda benar-benar terbatas, seperti yang Anda sebutkan karena proxy dan load balancers. Untungnya, baik Node.JS dan IIS berikutnya melakukan pekerjaan yang layak dengan peran ini juga.
Tracker1
Penasaran: operator mana yang memblokir WebSocket di port 80? Yang memblokir WebSocket aman (WSS) pada port 443? Yang terakhir ini menyiratkan proksi web MITM transparan dan transparan .. tidak pernah melihat itu di jaringan publik (hanya yang korporat), karena memerlukan penginstalan sertifikat CA baru ke dalam peramban.
oberstet
Misalnya musuh, saat ini, Vodafone Italy memblokir WS pada port 80, tetapi memungkinkan WSS pada port 443. Anda dapat menguji operator apa pun dengan mudah melalui halaman rumah kami, yang dapat Anda akses di HTTP dan HTTPS. Mencoba WebSockets dan jatuh kembali ke HTTP jika diblokir. Gunakan URL ini untuk menampilkan widget di tengah yang melaporkan transportasi saat ini: lightstreamer.com/?s
Alessandro Alinone
17

Sebagian besar keluhan yang saya baca tentang soket web dan keamanan berasal dari vendor keamanan keamanan browser web dan alat keamanan firewall. Masalahnya adalah mereka tidak tahu bagaimana melakukan analisis keamanan lalu lintas websockets, karena setelah melakukan upgrade dari HTTP ke protokol binary websocket, konten paket dan artinya adalah aplikasi spesifik (berdasarkan pada apa pun program Anda). Ini jelas mimpi buruk logistik bagi perusahaan-perusahaan ini yang mata pencahariannya didasarkan pada analisis dan klasifikasi semua lalu lintas internet Anda. :)

Tim Lovell-Smith
sumber
11

WebSockets tidak berfungsi di browser web yang lebih lama, dan yang mendukungnya seringkali memiliki implementasi yang berbeda. Itu satu-satunya alasan bagus mengapa mereka tidak digunakan sepanjang waktu di tempat AJAX.

jli
sumber
8
Alasan yang lebih baik adalah bahwa permintaan AJAX adalah permintaan HTTP normal yang artinya dapat mengambil sumber daya HTTP; WebSockets tidak dapat melakukan itu.
Dan D.
@Dan Bagaimana jika misalnya file gambar dikirim sebagai base64, CSS sebagai teks, JavaScript juga sebagai teks dan kemudian ditambahkan ke dokumen? Apakah itu masuk akal?
Jack
@DanD. +1, saya setuju, saya kira saya lebih banyak mendekati pertanyaan dari konteks streaming data yang cepat seperti pada contoh pertanyaan, tapi ini pasti benar.
jli
@Dan D - kadang-kadang Anda tidak ingin semua omong kosong itu melewati batas, seperti cookie dan header ...
vsync
8
@DanD., HTTP dan WebSocket adalah dua protokol yang berbeda, Tentu saja kami tidak dapat meminta sumber daya HTTP menggunakan protokol WebSocket karena alasan yang sama kami tidak dapat meminta sumber daya WebSocket menggunakan protokol HTTP! Itu tidak berarti bahwa klien tidak dapat meminta file html dan / atau gambar yang dikirim melalui protokol Websocket.
Pacerier
2

Saya tidak berpikir kita bisa melakukan perbandingan yang jelas antara Websockets dan HTTP karena mereka bukan saingan atau memecahkan masalah yang sama.

Websockets adalah pilihan tepat untuk menangani streaming data dua arah yang berumur panjang dalam waktu yang hampir bersamaan, sedangkan REST bagus untuk komunikasi sesekali. Menggunakan websockets adalah investasi yang cukup besar, oleh karena itu itu merupakan kerja keras untuk koneksi sesekali.

Anda mungkin menemukan bahwa Websockets melakukan lebih baik ketika ada beban tinggi, HTTP sedikit lebih cepat dalam beberapa kasus karena dapat memanfaatkan caching. Membandingkan REST dengan Websockets seperti membandingkan apel dengan jeruk.

Kita harus memeriksa mana yang memberikan solusi yang lebih baik untuk aplikasi kita, mana yang paling cocok dalam kasus penggunaan kita menang.

Gaurav Gandhi
sumber
1
pertanyaannya adalah tentang AJAX secara umum, bukan REST pada khususnya. Memang benar bahwa AJAX dapat digunakan untuk REST, tetapi juga digunakan untuk polling dan polling panjang. Meskipun saya setuju dengan kesimpulan Anda (seperti yang Anda tahu dari jawaban saya), saya pikir jawaban Anda dapat mencerminkan perbedaan (perhatikan bahwa Websockets dapat digunakan untuk REST juga, meskipun tidak dengan menggunakan metode HTTP).
Myst
@Myst saya setuju dengan Anda.
Gaurav Gandhi
1

Contoh perbedaan antara HTTP dan Websockets dalam bentuk lib ukuran klien yang dapat menangani endpoint Websocket seperti REST API dan endpoint RESTful seperti Websockets pada klien. https://github.com/mikedeshazer/sockrest Juga, bagi mereka yang mencoba untuk mengkonsumsi API websocket pada klien atau sebaliknya cara mereka terbiasa. Libs / sockrest.js cukup menjelaskan perbedaan (atau lebih tepatnya seharusnya).

Mike D
sumber