11 poin oleh GN⁺ 2025-04-13 | 3 komentar | Bagikan ke WhatsApp
  • 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 ini disembunyikan.]
 
[Komentar ini disembunyikan.]
 
GN⁺ 2025-04-13
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

    • Sering kali WebSockets tidak diperlukan. Server-Sent Events (SSE) adalah solusi yang lebih sederhana. Sayang sekali SSE kurang mendapat perhatian
  • 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 => ...)

    • Upgrade request membingungkan. Menjengkelkan karena server WebSocket tertanam di dalam server HTTP tetapi tidak terintegrasi
    • Alih-alih memakai ulang middleware yang membaca headers['authorization'] pada permintaan WebSocket, kita harus mengakses objek connectionParams yang berpura-pura menjadi header permintaan
    • API WebSocket di browser lebih nyaman ditangani daripada EventSource
  • Video 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

    • Arsitek bersikeras bahwa WebSocket dibutuhkan
    • POC tidak memerlukan XHR maupun WebSocket. Ini adalah alur pembelian yang berurutan
    • Pada akhirnya jadi menyediakan WebSocket yang tidak perlu
  • 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 adalah protokol yang lebih sederhana yang dirancang untuk komunikasi dua arah. Dengan satu koneksi, aliran data lebih mudah dikendalikan. Manajemen status dan pemulihan kehilangan koneksi lebih mudah. Autentikasi dan kontrol akses menjadi lebih sederhana
  • 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