- WebSocket berguna untuk komunikasi real-time, tetapi tidak selalu diperlukan, dan alternatif berbasis HTTP bisa lebih sederhana serta lebih andal
- Dalam pemrosesan transaksi, pengelolaan koneksi, dan kompleksitas server, WebSocket dapat menimbulkan overhead yang berlebihan
- Dengan memanfaatkan HTTP Streaming dan pustaka
eventkit, sinkronisasi real-time dan pemrosesan event tetap dapat dilakukan tanpa WebSocket
Apa itu WebSocket
- WebSocket adalah teknologi untuk membuka kanal komunikasi dua arah yang persisten antara klien dan server
- Koneksi dimulai melalui HTTP, tetapi setelah itu komunikasi berlangsung dengan protokol terpisah
- Sering digunakan untuk membangun aplikasi real-time dan berguna karena mendukung komunikasi dua arah
Pesan WebSocket tidak bersifat transaksional
- WebSocket tidak menjamin keterkaitan langsung antara permintaan dan respons
- Perintah perubahan status dan pesan hasilnya dapat tiba bercampur dalam stream yang sama
- Misalnya, jika satu klien mengubah status lalu terjadi error, sulit mengetahui error itu berasal dari perintah yang mana
- Solusinya adalah menyertakan
requestId untuk menghubungkan perintah dan respons, tetapi ini menambah kompleksitas dan biaya pengelolaan
- Pendekatan yang lebih sederhana adalah mengirim perintah dengan metode transaksional berbasis HTTP, lalu memakai WebSocket hanya untuk menyiarkan perubahan status
- Sisi pengiriman dapat dipisahkan sebagai permintaan HTTP, dan sisi penerimaan sebagai WebSocket atau metode streaming lain
Sulitnya mengelola siklus hidup koneksi WebSocket
- Saat menggunakan WebSocket, Anda harus menangani sendiri awal koneksi, akhir koneksi, error, reconnect, dan sebagainya
- Contoh penanganan dasar di browser mencakup event saat koneksi dibuka, pesan diterima, error terjadi, dan koneksi ditutup
- Diperlukan logika tambahan seperti reconnect, buffering pesan, dan exponential backoff
- Sebaliknya, HTTP memiliki awal dan akhir yang jelas per permintaan sehingga implementasinya lebih sederhana
- Pengelolaan siklus hidup yang rumit ini hanya layak jika memang ada alasan kuat untuk memakai WebSocket
Kompleksitas kode server meningkat
- WebSocket harus menangani permintaan upgrade HTTP, yang memerlukan logika handshake tambahan
- Header khusus seperti
Sec-WebSocket-Key harus divalidasi, dan header respons harus dikembalikan dengan tepat
- Setelah koneksi WebSocket terbentuk, status penerimaan dan pengiriman pesan yang berkelanjutan harus dipertahankan, dan masalah seperti pemrosesan frame parsial juga bisa muncul
- Dibanding hanya menggunakan HTTP, debugging dan penanganan error menjadi lebih sulit
- Framework memang mengabstraksikan sebagian proses, tetapi kompleksitas dasarnya tetap ada
Alternatif: HTTP Streaming
- HTTP pada dasarnya adalah protokol yang mendukung streaming, sehingga aliran data dapat dikirim secara real-time, bukan hanya seluruh file sekaligus
- Fungsi sisi penerimaan dari WebSocket yang sudah ada dapat digantikan dengan HTTP streaming
- Dengan menggunakan generator asinkron, pembaruan status dapat diproses dalam bentuk stream
- Alur sisi server
- Pembaruan status dilakukan di fungsi pemroses perintah
- Klien yang terhubung menerima data melalui generator setiap kali nilai baru muncul
- Perintah perubahan status dikirim melalui HTTP POST, dan stream real-time dilanggani lewat permintaan GET
- Alur sisi klien
- Menerima data real-time melalui Fetch API dan Stream Reader
- Setelah teks didekode, UI diperbarui
- Dengan struktur ini, sinkronisasi status real-time dapat diimplementasikan tanpa WebSocket
Bonus: pengenalan pustaka eventkit
eventkit adalah pustaka yang memudahkan penyusunan dan pengamatan stream asinkron
- Mirip dengan RxJS, tetapi pengelolaan efek sampingnya ditingkatkan dan dirancang berbasis generator
- Jika pembaruan status didorong ke stream, klien dapat menerimanya secara real-time
- Melalui
Stream dan AsyncObservable, implementasi sederhana dimungkinkan di sisi server maupun klien
- Penggunaan eventkit di sisi server
- Mendorong perubahan status ke Stream, lalu klien melanggani stream tersebut
- Penggunaan eventkit di sisi klien
- Menerima data stream, mendekodenya, lalu memperbarui UI
- Repositori GitHub resmi dan panduan HTTP Streaming juga tersedia
GitHub: https://github.com/hntrl/eventkit
3 komentar
Komentar Hacker News
Saya rasa HTTP streaming tidak dirancang dengan pola ini dalam pikiran. HTTP streaming digunakan untuk memecah data besar menjadi bagian-bagian kecil. Jika memakai streaming seperti mekanisme pub/sub, Anda bisa menyesal. Perantara HTTP tidak mengharapkan pola trafik seperti ini (NGINX, CloudFlare, dll.). Setiap kali koneksi WiFi terputus, fetch API sepertinya akan melempar error karena permintaan gagal
Mengirim RequestID ke server untuk mendapatkan siklus request/response bukan hal yang aneh atau berlebihan. Untuk aplikasi serius, selalu layak memiliki API seperti
send(message).then(res => ...)headers['authorization']pada permintaan WebSocket, kita harus mengakses objekconnectionParamsyang berpura-pura menjadi header permintaanVideo streaming membuat klien meminta chunk berdasarkan range, bukan melalui satu koneksi HTTP tunggal
Sebaiknya gunakan SSE alih-alih eventkit
Untuk POC, saya akan memakai pengiriman form HTTP tradisional. Tidak butuh yang lain
Masalah HTTP2 adalah server push ditambahkan di atas protokol yang sudah ada. HTTP adalah protokol pengiriman resource, sehingga menambah overhead yang tidak perlu. Tujuan utama HTTP2 adalah agar server bisa mendorong file/resource ke klien lebih awal untuk mengurangi latensi round-trip
WebSockets tidak mengirim sebagai stream, melainkan sebagai datagram (paket). API WebSockets pada pustaka JavaScript tidak bisa menangani backpressure dan tidak bisa menangani semua error. Perlu hati-hati jika ingin memakainya seperti TCP stream
Saya menyesal setelah menerapkan WebSockets ke produksi. Ada masalah seperti NGINX memutus koneksi setelah 4/8 jam, browser tidak tersambung ulang setelah sleep, dan sebagainya. Jika memungkinkan, hindari WebSockets dan koneksi jangka panjang
Ada persepsi yang terlalu ideal terhadap WebSockets. Ada kecenderungan memakai WebSockets untuk kasus penggunaan streaming/real-time. WebSockets menghilangkan kesederhanaan dan keuntungan dari tool HTTP. Solusi untuk perubahan server streaming adalah h2/h3 dan SSE. Jika bisa dibatch hingga maksimal 0.5 req/s per klien, maka WebSockets tidak diperlukan
Siapa pun yang tertarik pada HTTP streaming sebaiknya melihat Braid-HTTP. Ini memperluas HTTP secara elegan untuk event streaming dan menyediakan protokol sinkronisasi status yang kuat