Protokol WebSockets vs HTTP

330

Ada banyak blog dan diskusi tentang websocket dan HTTP, dan banyak pengembang dan situs sangat mengadvokasi websockets, tetapi saya masih tidak mengerti mengapa.

misalnya (argumen pecinta websocket):

HTML5 Web Sockets mewakili evolusi berikutnya dari komunikasi web — saluran komunikasi dua arah penuh, dua arah yang beroperasi melalui soket tunggal melalui Web. ( http://www.websocket.org/quantum.html )

HTTP mendukung streaming: permintaan streaming badan (Anda menggunakannya saat mengunggah file besar) dan streaming tanggapan tubuh.

Selama membuat koneksi dengan WebSocket, klien dan server bertukar data per frame yang masing-masing 2 byte, dibandingkan dengan 8 kg header http ketika Anda melakukan polling terus menerus.

Mengapa 2 byte itu tidak termasuk tcp dan di bawah protokol tcp?

GET /about.html HTTP/1.1
Host: example.org

Ini adalah ~ 48 byte header http.

http chunked encoding - https://en.wikipedia.org/wiki/Chunked_transfer_encoding :

23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0
  • Jadi, biaya overhead per setiap potongan tidak besar.

Juga kedua protokol bekerja melalui TCP, sehingga semua masalah TCP dengan koneksi jangka panjang masih ada.

Pertanyaan:

  1. Mengapa protokol soket web lebih baik?
  2. Mengapa itu diterapkan alih-alih memperbarui protokol http?
4esn0k
sumber
2
Apa pertanyaan Anda?
Jonas
@ Jonas, 1) mengapa protokol websockets lebih baik? 2) Mengapa ini diterapkan daripada memperbarui protokol http? 3) Mengapa websockets sangat dipromosikan?
4esn0k
@ JoachimPileborg, Anda dapat melakukannya dengan soket TCP atau http juga untuk aplikasi desktop; dan Anda harus menggunakan WebRTC untuk membuat komunikasi browser-ke-browser untuk situs web
4esn0k
@ JoachimPileborg, ini adalah webRTC untuk browser-ke-browser, bukan websockets
4esn0k
@ 4esn0k, WS tidak lebih baik, mereka berbeda dan lebih baik untuk beberapa tugas tertentu. 3) Ini adalah fitur baru yang orang harus sadari dan membuka kemungkinan baru untuk Web
Jonas

Jawaban:

491

1) Mengapa protokol WebSockets lebih baik?

WebSockets lebih baik untuk situasi yang melibatkan komunikasi latensi rendah terutama untuk latensi rendah untuk pesan klien ke server. Untuk data server ke klien, Anda bisa mendapatkan latensi yang cukup rendah menggunakan koneksi lama dan transfer terpotong. Namun, ini tidak membantu latensi klien ke server yang memerlukan koneksi baru untuk dibuat untuk setiap klien ke server pesan.

Jabat tangan HTTP 48 byte Anda tidak realistis untuk koneksi browser HTTP dunia nyata di mana sering ada beberapa kilobyte data yang dikirim sebagai bagian dari permintaan (di kedua arah) termasuk banyak header dan data cookie. Berikut adalah contoh permintaan / tanggapan untuk menggunakan Chrome:

Contoh permintaan (2800 byte termasuk data cookie, 490 byte tanpa data cookie):

GET / HTTP/1.1
Host: www.cnn.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.68 Safari/537.17
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: [[[2428 byte of cookie data]]]

Contoh respons (355 byte):

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 13 Feb 2013 18:56:27 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: CG=US:TX:Arlington; path=/
Last-Modified: Wed, 13 Feb 2013 18:55:22 GMT
Vary: Accept-Encoding
Cache-Control: max-age=60, private
Expires: Wed, 13 Feb 2013 18:56:54 GMT
Content-Encoding: gzip

Baik HTTP dan WebSockets memiliki jabat tangan koneksi ukuran awal yang setara, tetapi dengan koneksi WebSocket jabat tangan awal dilakukan sekali dan kemudian pesan kecil hanya memiliki 6 byte overhead (2 untuk header dan 4 untuk nilai mask). Overhead latensi tidak begitu banyak dari ukuran header, tetapi dari logika untuk mengurai / menangani / menyimpan header tersebut. Selain itu, latensi penyiapan koneksi TCP mungkin merupakan faktor yang lebih besar daripada ukuran atau waktu pemrosesan untuk setiap permintaan.

2) Mengapa ini diterapkan alih-alih memperbarui protokol HTTP?

Ada upaya untuk merekayasa ulang protokol HTTP untuk mencapai kinerja yang lebih baik dan latensi yang lebih rendah seperti SPDY , HTTP 2.0 dan QUIC . Ini akan meningkatkan situasi untuk permintaan HTTP normal, tetapi kemungkinan WebSockets dan / atau WebRTC DataChannel masih akan memiliki latensi yang lebih rendah untuk transfer data klien ke server daripada protokol HTTP (atau akan digunakan dalam mode yang sangat mirip dengan WebSockets bagaimanapun).

Perbarui :

Berikut adalah kerangka kerja untuk berpikir tentang protokol web:

  • TCP : lapisan transport pesanan tingkat rendah, dua arah, dupleks penuh, dan terjamin. Tidak ada dukungan browser (kecuali melalui plugin / Flash).
  • HTTP 1.0 : protokol transport permintaan-respons berlapis pada TCP. Klien membuat satu permintaan penuh, server memberikan satu respons penuh, dan kemudian koneksi ditutup. Metode permintaan (GET, POST, HEAD) memiliki makna transaksional khusus untuk sumber daya di server.
  • HTTP 1.1 : mempertahankan sifat permintaan-respons HTTP 1.0, tetapi memungkinkan koneksi tetap terbuka untuk beberapa permintaan penuh / respons penuh (satu respons per permintaan). Masih memiliki tajuk lengkap dalam permintaan dan tanggapan tetapi koneksi digunakan kembali dan tidak ditutup. HTTP 1.1 juga menambahkan beberapa metode permintaan tambahan (OPTIONS, PUT, DELETE, TRACE, CONNECT) yang juga memiliki makna transaksional tertentu. Namun, seperti yang tercantum dalam pengantar proposal rancangan HTTP 2.0, pipelining HTTP 1.1 tidak digunakan secara luas sehingga ini sangat membatasi utilitas HTTP 1.1 untuk menyelesaikan latensi antara browser dan server.
  • Jajak pendapat panjang : semacam "retas" ke HTTP (baik 1.0 atau 1.1) di mana server tidak segera merespons (atau hanya merespons sebagian dengan tajuk) terhadap permintaan klien. Setelah respons server, klien segera mengirim permintaan baru (menggunakan koneksi yang sama jika melalui HTTP 1.1).
  • Streaming HTTP : beragam teknik (respons multi bagian / terpotong) yang memungkinkan server mengirim lebih dari satu respons ke satu permintaan klien. W3C menstandarkan ini sebagai Server-Sent Events menggunakan text/event-streamtipe MIME. API browser (yang cukup mirip dengan API WebSocket) disebut API EventSource.
  • Dorongan server / server : ini adalah istilah umum yang mencakup jajak pendapat panjang dan streaming HTTP. Pustaka komet biasanya mendukung berbagai teknik untuk mencoba dan memaksimalkan dukungan lintas-browser dan lintas-server.
  • WebSockets : lapisan transport bawaan TCP yang menggunakan handshake Upgrade HTTP friendly. Tidak seperti TCP, yang merupakan transport streaming, WebSockets adalah transport berbasis pesan: pesan dibatasi pada kabel dan dipasang kembali secara penuh sebelum dikirim ke aplikasi. Koneksi WebSocket bersifat dua arah, dupleks penuh, dan berumur panjang. Setelah permintaan / respons jabat tangan awal, tidak ada semantik transaksional dan hanya ada sedikit overhead pesan. Klien dan server dapat mengirim pesan kapan saja dan harus menangani penerimaan pesan secara tidak sinkron.
  • SPDY : proposal yang diprakarsai Google untuk memperluas HTTP menggunakan protokol kawat yang lebih efisien tetapi mempertahankan semua semantik HTTP (permintaan / tanggapan, cookie, penyandian). SPDY memperkenalkan format pembingkaian baru (dengan frame yang panjangnya diawali) dan menentukan cara untuk meletakkan pasangan permintaan / respons HTTP ke lapisan pembingkaian baru. Header dapat dikompresi dan header baru dapat dikirim setelah koneksi dibuat. Ada implementasi dunia nyata dari SPDY di browser dan server.
  • HTTP 2.0 : memiliki tujuan yang mirip dengan SPDY: mengurangi latensi dan overhead HTTP sambil mempertahankan semantik HTTP. Draf saat ini berasal dari SPDY dan mendefinisikan handshake upgrade dan framing data yang sangat mirip dengan standar WebSocket untuk handshake dan framing. Proposal rancangan HTTP 2.0 alternatif (httpbis-speed-mobility) sebenarnya menggunakan WebSockets untuk lapisan transport dan menambahkan multiplexing dan pemetaan HTTP SPDY sebagai ekstensi WebSocket (ekstensi WebSocket dinegosiasikan selama jabat tangan).
  • WebRTC / CU-WebRTC : proposal untuk memungkinkan konektivitas peer-to-peer antara browser. Ini dapat memungkinkan komunikasi latensi rata-rata dan maksimum yang lebih rendah karena transportasi yang mendasarinya adalah SDP / datagram daripada TCP. Hal ini memungkinkan pengiriman paket / pesan out-of-order yang menghindari masalah TCP dari lonjakan latensi yang disebabkan oleh paket yang jatuh yang menunda pengiriman semua paket berikutnya (untuk menjamin pengiriman dalam pesanan).
  • QUIC : adalah protokol eksperimental yang bertujuan mengurangi latensi web dibandingkan TCP. Di permukaan, QUIC sangat mirip dengan TCP + TLS + SPDY diimplementasikan pada UDP. QUIC menyediakan kontrol multiplexing dan flow yang setara dengan HTTP / 2, keamanan setara dengan TLS, dan semantik koneksi, keandalan, dan kontrol kemacetan yang setara dengan TCP. Karena TCP diimplementasikan dalam kernel sistem operasi, dan firmware middlebox, membuat perubahan signifikan pada TCP hampir tidak mungkin. Namun, karena QUIC dibangun di atas UDP, QUIC tidak memiliki batasan seperti itu. QUIC dirancang dan dioptimalkan untuk semantik HTTP / 2.

Referensi :

kanaka
sumber
1
>> Namun, ini tidak membantu latensi klien ke server yang memerlukan koneksi baru untuk dibuat untuk setiap klien ke server pesan. - bagaimana dengan streaming badan tanggapan? saya tahu, XMLHttpRequest API tidak mengizinkan ini, tetapi itu ada. dengan streaming ke server Anda dapat melakukan streaming dari sisi klien.
4esn0k
8
@ Pilip, dia mengajukan pertanyaan yang saya ingin teliti dan dokumentasikan dengan cermat. Pertanyaan WebSockets vs mekanisme berbasis HTTP lain muncul cukup sering jadi sekarang ada referensi yang baik untuk ditautkan. Tapi ya, sepertinya penanya mencari bukti untuk mendukung gagasan yang sudah terbentuk sebelumnya tentang WebSockets vs HTTP terutama karena ia tidak pernah memilih jawaban atau memberi hadiah.
kanaka
9
Terima kasih banyak atas ikhtisar protokol yang sangat bagus dan tepat ini.
Martin Meeser
2
@WardC caniuse.com memberi informasi kompatibilitas browser (termasuk ponsel).
kanaka
3
@ www139, tidak, pada tingkat protokol WebSocket koneksi tetap terbuka sampai satu sisi atau sisi lain menutup koneksi. Anda mungkin juga harus khawatir tentang timeout TCP (masalah dengan protokol berbasis TCP), tetapi segala jenis lalu lintas setiap satu atau dua menit akan membuat koneksi tetap terbuka. Bahkan, definisi protokol WebSocket menentukan jenis bingkai ping / pong, meskipun tanpa itu Anda dapat mengirim byte tunggal (ditambah header dua byte) dan itu akan membuat koneksi tetap terbuka. 2-3 byte setiap beberapa menit bukanlah dampak bandwidth yang signifikan sama sekali.
kanaka
130

Anda tampaknya menganggap bahwa WebSocket adalah pengganti HTTP. Bukan itu. Itu ekstensi.

Kasus penggunaan utama WebSockets adalah aplikasi Javascript yang berjalan di browser web dan menerima data real-time dari server. Game adalah contoh yang bagus.

Sebelum WebSockets, satu-satunya metode untuk aplikasi Javascript untuk berinteraksi dengan server adalah melalui XmlHttpRequest. Tetapi ini memiliki kelemahan utama: Server tidak dapat mengirim data kecuali klien secara eksplisit memintanya.

Tetapi fitur WebSocket baru memungkinkan server untuk mengirim data kapan pun diinginkan. Hal ini memungkinkan untuk mengimplementasikan game berbasis browser dengan latensi yang jauh lebih rendah dan tanpa harus menggunakan peretasan jelek seperti AJAX polling panjang atau plugin browser.

Jadi mengapa tidak menggunakan HTTP normal dengan permintaan dan tanggapan yang dialirkan

Dalam komentar ke jawaban lain Anda menyarankan untuk melakukan streaming permintaan klien dan badan respons secara tidak sinkron.

Bahkan, WebSockets pada dasarnya itu. Upaya untuk membuka koneksi WebSocket dari klien terlihat seperti permintaan HTTP pada awalnya, tetapi arahan khusus di header (Upgrade: websocket) memberi tahu server untuk mulai berkomunikasi dalam mode asinkron ini. Draft pertama protokol WebSocket tidak lebih dari itu dan beberapa jabat tangan untuk memastikan bahwa server benar-benar memahami bahwa klien ingin berkomunikasi secara tidak sinkron. Tapi kemudian disadari bahwa server proxy akan bingung dengan itu, karena mereka terbiasa dengan model permintaan / respons HTTP yang biasa. Sebuah potensi skenario serangan terhadap proxy server ditemukan. Untuk mencegah ini, perlu untuk membuat lalu lintas WebSocket terlihat tidak seperti lalu lintas HTTP normal. Itu sebabnya kunci masking diperkenalkan diversi terakhir dari protokol .

Philipp
sumber
>> he server tidak dapat mengirim data kecuali klien secara eksplisit memintanya .; Browser web harus memulai koneksi WebSockets ... sama seperti untuk XMLHttpRequest
4esn0k
18
@ 4esn0k Browser tidak melakukan koneksi websocket. Tetapi setelah itu ditetapkan, kedua belah pihak dapat mengirim data kapan pun mereka mau. Itu tidak berlaku untuk XmlHttpRequest.
Philipp
1
MENGAPA ini tidak mungkin dengan HTTP?
4esn0k
4
@ Pilip, game adalah contoh yang bagus di mana WebSockets bersinar. Namun, ini bukan data waktu-nyata dari server tempat Anda mendapatkan kemenangan terbesar. Anda bisa mendapatkan latensi server-> klien yang hampir sebaik menggunakan streaming HTTP / koneksi lama. Dan dengan permintaan lama, server dapat secara efektif mengirim kapan pun mereka memiliki data karena klien telah mengirim permintaan dan server "menahan permintaan" hingga memiliki data. Kemenangan terbesar untuk WebSockets adalah dengan latensi server- klien (dan karenanya pulang-pergi). Klien dapat mengirim kapan pun diinginkan tanpa meminta overhead adalah kunci sebenarnya.
kanaka
1
@ Pilip, catatan lain: ada metode lain selain XMLHttpRequest dan WebSockets untuk JavaScript untuk berinteraksi dengan server termasuk iframes tersembunyi dan tag skrip polling panjang. Lihat halaman wikipedia Komet untuk detail lebih lanjut: en.wikipedia.org/wiki/Comet_(programming)
kanaka
27

API REST reguler menggunakan HTTP sebagai protokol dasar untuk komunikasi, yang mengikuti paradigma permintaan dan respons, artinya komunikasi melibatkan klien yang meminta beberapa data atau sumber daya dari server, dan server merespons kembali ke klien itu. Namun, HTTP adalah protokol tanpa kewarganegaraan, sehingga setiap siklus permintaan-respons pada akhirnya harus mengulang informasi header dan metadata. Ini menimbulkan latensi tambahan jika siklus permintaan-respons yang sering diulang.

http

Dengan WebSockets, meskipun komunikasi masih dimulai sebagai jabat tangan HTTP awal, itu adalah peningkatan lebih lanjut untuk mengikuti protokol WebSockets (yaitu jika server dan klien mematuhi protokol karena tidak semua entitas mendukung protokol WebSockets).

Sekarang dengan WebSockets, dimungkinkan untuk membuat koneksi duplex penuh dan persisten antara klien dan server. Ini berarti bahwa tidak seperti permintaan dan respons, koneksi tetap terbuka selama aplikasi berjalan (yaitu persisten), dan karena itu adalah dupleks penuh, komunikasi simultan dua arah dimungkinkan, sekarang server dapat memulai komunikasi dan 'dorong' beberapa data ke klien ketika data baru (yang diminati klien) tersedia.

soket web

Protokol WebSockets stateful dan memungkinkan Anda untuk menerapkan pola pesan Publikasikan-Berlangganan (atau Pub / Sub) yang merupakan konsep utama yang digunakan dalam teknologi real-time di mana Anda bisa mendapatkan pembaruan baru dalam bentuk dorongan server tanpa klien harus meminta (menyegarkan halaman) berulang kali. Contoh aplikasi tersebut adalah pelacakan lokasi mobil Uber, Pemberitahuan Push, Pembaruan harga pasar saham dalam waktu nyata, obrolan, permainan multi pemain, alat kolaborasi online langsung, dll.

Anda dapat memeriksa artikel menyelam yang mendalam di Websockets yang menjelaskan sejarah protokol ini, bagaimana protokol ini muncul, apa yang digunakan untuk itu dan bagaimana Anda dapat mengimplementasikannya sendiri.

Ini adalah video dari presentasi yang saya lakukan tentang WebSockets dan perbedaannya dengan menggunakan REST APIs biasa: Standarisasi dan meningkatkan peningkatan eksponensial dalam streaming data

Srushtika Neelakantam
sumber
24

Untuk TL; DR, berikut adalah 2 sen dan versi yang lebih sederhana untuk pertanyaan Anda:

  1. WebSockets memberikan manfaat ini melalui HTTP:

    • Koneksi stateful persisten selama durasi koneksi
    • Latensi rendah: hampir komunikasi waktu-nyata antara server / klien karena tidak ada overhead untuk membangun kembali koneksi untuk setiap permintaan seperti yang dipersyaratkan HTTP.
    • Dupleks penuh: baik server dan klien dapat mengirim / menerima secara bersamaan
  2. WebSocket dan protokol HTTP telah dirancang untuk memecahkan masalah yang berbeda, IE WebSocket dirancang untuk meningkatkan komunikasi dua arah sedangkan HTTP dirancang untuk menjadi tanpa kewarganegaraan, didistribusikan menggunakan model permintaan / respons. Selain berbagi port untuk alasan warisan (firewall / penetrasi proxy), tidak ada banyak kesamaan untuk menggabungkannya menjadi satu protokol.

Devy
sumber
3
Penting bahwa Anda menyebutkan istilah stateful dan stateless dalam perbandingan Anda (Y)
Utsav T
15

Mengapa protokol soket web lebih baik?

Saya tidak berpikir kita bisa membandingkan mereka berdampingan seperti siapa yang lebih baik. Itu tidak akan menjadi perbandingan yang adil hanya karena mereka menyelesaikan dua masalah yang berbeda . Persyaratan mereka berbeda. Ini akan seperti membandingkan apel dengan jeruk. Mereka berbeda.

HTTP adalah protokol permintaan-respons. Klien (browser) menginginkan sesuatu, server memberikannya. Itu adalah. Jika yang diinginkan klien data besar, server mungkin mengirim data streaming untuk membatalkan masalah buffer yang tidak diinginkan. Di sini persyaratan atau masalah utama adalah bagaimana membuat permintaan dari klien dan bagaimana menanggapi sumber daya (hybertext) yang mereka minta. Di situlah HTTP bersinar.

Dalam HTTP, hanya permintaan klien. Server hanya merespons.

WebSocket bukan protokol permintaan-respons di mana hanya klien yang dapat meminta. Ini adalah soket (sangat mirip dengan soket TCP). Berarti sekali koneksi terbuka, kedua belah pihak dapat mengirim data sampai garis bawah koneksi TCP ditutup. Ini seperti soket normal. Satu-satunya perbedaan dengan soket TCP adalah websocket dapat digunakan di web. Di web, kami memiliki banyak batasan untuk soket normal. Sebagian besar firewall akan memblokir port lain selain 80 dan 433 yang digunakan HTTP. Proxy dan perantara juga akan bermasalah. Jadi untuk membuat protokol lebih mudah untuk digunakan ke infrastruktur websocket yang ada, gunakan handshake HTTP untuk memutakhirkan. Itu berarti ketika koneksi pertama kali akan dibuka, klien mengirim permintaan HTTP untuk memberi tahu server dengan mengatakan "Itu bukan permintaan HTTP, silakan tingkatkan ke protokol websocket".

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Setelah server memahami permintaan dan ditingkatkan ke protokol websocket, tidak ada protokol HTTP yang berlaku lagi.

Jadi jawaban saya adalah tidak ada yang lebih baik dari yang lain. Mereka sangat berbeda.

Mengapa itu diterapkan alih-alih memperbarui protokol http?

Kita bisa membuat semuanya dengan nama yang disebut HTTP juga. Tapi bisakah kita? Jika mereka dua hal yang berbeda, saya akan lebih suka dua nama yang berbeda. Begitu juga Hickson dan Michael Carter .

FranXho
sumber
6

Jawaban lain tampaknya tidak menyentuh aspek kunci di sini, dan itu adalah Anda tidak menyebutkan memerlukan dukungan browser web sebagai klien. Sebagian besar batasan HTTP sederhana di atas mengasumsikan Anda akan bekerja dengan implementasi browser / JS.

Protokol HTTP sepenuhnya mampu komunikasi dupleks penuh; itu sah untuk memiliki klien melakukan POST dengan transfer encoding chunked, dan server untuk mengembalikan respons dengan badan encoding chunked. Ini akan menghapus overhead header hanya pada waktu init.

Jadi jika semua yang Anda cari adalah dupleks penuh, kontrol klien dan server, dan tidak tertarik pada framing tambahan / fitur soket web, maka saya berpendapat bahwa HTTP adalah pendekatan yang lebih sederhana dengan latensi / CPU yang lebih rendah (meskipun latensi akan benar-benar hanya berbeda dalam mikrodetik atau kurang untuk keduanya).

paritas3
sumber