Mengirim data antar-browser dengan saluran data WebRTC

Mengirim data antara dua browser untuk komunikasi, permainan, atau transfer file bisa menjadi proses yang cukup rumit. Cara ini memerlukan penyiapan dan pembayaran server untuk menyampaikan data, dan mungkin menskalakannya ke beberapa pusat data. Dalam skenario ini, ada potensi latensi tinggi dan sulit untuk menjaga privasi data.

Masalah ini dapat diatasi dengan menggunakan RTCDataChannel API WebRTC untuk mentransfer data langsung dari satu peer ke peer lainnya. Artikel ini membahas dasar-dasar cara menyiapkan dan menggunakan saluran data, serta kasus penggunaan umum di web saat ini.

Mengapa saluran data lain?

Kami memiliki WebSocket, AJAX, dan Peristiwa Terkirim Server. Mengapa kita memerlukan saluran komunikasi lain? WebSocket bersifat dua arah, tetapi semua teknologi ini dirancang untuk komunikasi ke atau dari server.

RTCDataChannel menggunakan pendekatan yang berbeda:

  • Alat ini berfungsi dengan RTCPeerConnection API, yang memungkinkan konektivitas peer-to-peer. Hal ini dapat menghasilkan latensi yang lebih rendah - tanpa server perantara dan lebih sedikit 'hop'.
  • RTCDataChannel menggunakan Stream Control Transmission Protocol (SCTP), yang memungkinkan konfigurasi pengiriman ulang yang tidak sesuai urutan dan semantik pengiriman yang tidak sesuai.

RTCDataChannel kini tersedia dengan dukungan SCTP di desktop dan Android di Google Chrome, Opera, dan Firefox.

Peringatan: Pemberian sinyal, STUN, dan TURN

WebRTC mengaktifkan komunikasi peer-to-peer, tetapi masih memerlukan server untuk sinyal bertukar media dan metadata jaringan guna mem-bootstrap koneksi pembanding.

WebRTC menangani NAT dan firewall dengan:

  • Framework ICE untuk menetapkan jalur jaringan terbaik di antara pembanding.
  • Server STUN untuk memastikan IP dan port yang dapat diakses secara publik untuk setiap peer.
  • TURN server jika koneksi langsung gagal dan relai data diperlukan.

Untuk informasi lebih lanjut tentang cara kerja WebRTC dengan server untuk pemberian sinyal dan jaringan, lihat WebRTC di dunia nyata: STUN, TURN, dan pemberian sinyal.

Kemampuan

RTCDataChannel API mendukung kumpulan jenis data yang fleksibel. API ini dirancang untuk meniru WebSocket dengan tepat, dan RTCDataChannel mendukung string serta beberapa jenis biner dalam JavaScript, seperti Blob, ArrayBuffer, dan ArrayBufferView. Jenis ini dapat berguna saat bekerja dengan transfer file dan bermain game multiplayer.

RTCDataChannel dapat berfungsi dalam mode yang tidak dapat diandalkan dan tidak berurutan (analog dengan User Datagram Protocol atau UDP), mode andal dan diurutkan (analog dengan Transmission Control Protocol atau TCP), dan mode andal parsial:

  • Mode yang andal dan diurutkan menjamin transmisi pesan dan juga urutan pengiriman pesan tersebut. Ini membutuhkan overhead tambahan, sehingga berpotensi membuat mode ini lebih lambat.
  • Mode yang tidak dapat diandalkan dan tidak berurutan tidak menjamin setiap pesan terkirim ke sisi lain atau urutan pesan masuk. Hal ini menghilangkan overhead, sehingga mode ini dapat bekerja jauh lebih cepat.
  • Mode andal parsial menjamin transmisi pesan dalam kondisi tertentu, seperti waktu tunggu pengiriman ulang atau jumlah maksimum transmisi ulang. Urutan pesan juga dapat dikonfigurasi.

Performa untuk dua mode pertama hampir sama jika tidak ada paket yang hilang. Namun, dalam mode yang andal dan diurutkan, paket yang hilang menyebabkan paket lain terhalang di belakangnya, dan paket yang hilang mungkin sudah usang pada saat dikirim ulang dan tiba. Tentu saja, Anda dapat menggunakan beberapa saluran data dalam aplikasi yang sama, masing-masing dengan semantiknya yang andal atau tidak bisa diandalkan.

Berikut ini tabel yang bermanfaat dari High Performance Browser Networking oleh Ilya Grigorik:

TCPUDPSCTP
KeandalanAndalTidak dapat dipercayaDapat Dikonfigurasi
Pesan antarDipesanTidak diurutkanDapat Dikonfigurasi
PenularanBerorientasi pada byteBerorientasi pesanBerorientasi pesan
Kontrol alurYaTidakYa
Kontrol kemacetanYaTidakYa

Selanjutnya, Anda akan mempelajari cara mengonfigurasi RTCDataChannel untuk menggunakan mode yang andal, teratur, atau tidak dapat diandalkan dan tidak teratur.

Mengonfigurasi saluran data

Ada beberapa demo sederhana RTCDataChannel secara online:

Dalam contoh ini, browser membuat koneksi peer ke dirinya sendiri, kemudian membuat saluran data dan mengirim pesan melalui koneksi peer. Kemudian membuat saluran data dan mengirim pesan melalui koneksi peer. Akhirnya, pesan Anda muncul di kotak di sisi lain laman!

Kode untuk memulai ini singkat:

const peerConnection = new RTCPeerConnection();

// Establish your peer connection using your signaling channel here
const dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

dataChannel.onerror = (error) => {
  console.log("Data Channel Error:", error);
};

dataChannel.onmessage = (event) => {
  console.log("Got Data Channel Message:", event.data);
};

dataChannel.onopen = () => {
  dataChannel.send("Hello World!");
};

dataChannel.onclose = () => {
  console.log("The Data Channel is Closed");
};

Objek dataChannel dibuat dari koneksi peer yang sudah ada. Fitur ini dapat dibuat sebelum atau setelah pemberian sinyal. Anda kemudian meneruskan label untuk membedakan saluran ini dari yang lain dan serangkaian setelan konfigurasi opsional:

const dataChannelOptions = {
  ordered: false, // do not guarantee order
  maxPacketLifeTime: 3000, // in milliseconds
};

Anda juga dapat menambahkan opsi maxRetransmits (berapa kali untuk mencoba sebelum gagal), tetapi Anda hanya dapat menentukan maxRetransmits atau maxPacketLifeTime, bukan keduanya. Untuk semantik UDP, tetapkan maxRetransmits ke 0 dan ordered ke false. Untuk informasi selengkapnya, lihat RFC IETF ini: Stream Control Transmission Protocol dan Stream Control Transmission Protocol Partial Reliability Extension.

  • ordered: apakah saluran data harus menjamin keteraturan atau tidak
  • maxPacketLifeTime: waktu maksimum untuk mencoba dan mengirim ulang pesan yang gagal
  • maxRetransmits: frekuensi maksimum untuk mencoba dan mengirim ulang pesan yang gagal
  • protocol: memungkinkan penggunaan subprotokol, yang memberikan informasi meta untuk aplikasi
  • negotiated: jika disetel ke benar (true), menghapus penyiapan otomatis saluran data di aplikasi lain, yang menyediakan cara Anda sendiri untuk membuat saluran data dengan ID yang sama di sisi lain
  • id: memungkinkan Anda memberikan ID Anda sendiri untuk channel yang hanya dapat digunakan bersama dengan negotiated yang ditetapkan ke true)

Satu-satunya opsi yang perlu digunakan oleh sebagian besar orang adalah tiga opsi pertama: ordered, maxPacketLifeTime, dan maxRetransmits. Dengan SCTP (kini digunakan oleh semua browser yang mendukung WebRTC), andal dan urutannya adalah benar secara default. Sebaiknya gunakan opsi yang tidak dapat diandalkan dan tidak berurutan jika Anda menginginkan kontrol penuh dari lapisan aplikasi. Namun, dalam kebanyakan kasus, keandalan parsial akan sangat membantu.

Perlu diingat bahwa, seperti WebSocket, RTCDataChannel mengaktifkan peristiwa saat koneksi dibuat, ditutup, atau error, dan saat menerima pesan dari peer lainnya.

Apakah tantangan ini aman?

Enkripsi bersifat wajib untuk semua komponen WebRTC. Dengan RTCDataChannel, semua data diamankan dengan Datagram Transport Layer Security (DTLS). DTLS adalah turunan dari SSL, yang berarti data Anda akan seaman menggunakan koneksi berbasis SSL standar. DTLS distandardisasi dan disertakan di semua browser yang mendukung WebRTC. Untuk informasi selengkapnya, lihat Wiki Wireshark.

Ubah cara Anda berpikir tentang data

Menangani data dalam jumlah besar bisa menjadi masalah dalam JavaScript. Seperti yang ditunjukkan developer Sharefest, ini mengharuskan Anda memikirkan data dengan cara baru. Jika Anda mentransfer file yang lebih besar dari jumlah memori yang Anda miliki, Anda harus memikirkan cara baru untuk menyimpan informasi ini. Di sinilah teknologi, seperti FileSystem API, mulai berperan, seperti yang Anda lihat berikutnya.

Membangun aplikasi berbagi file

Pembuatan aplikasi web yang dapat berbagi file di browser kini dapat dilakukan dengan RTCDataChannel. Membuat di atas RTCDataChannel berarti data file yang ditransfer dienkripsi dan tidak menyentuh server penyedia aplikasi. Fungsi ini, dikombinasikan dengan kemungkinan terhubung ke banyak klien untuk berbagi lebih cepat, membuat aktivitas berbagi file WebRTC menjadi kandidat kuat untuk web.

Beberapa langkah diperlukan agar transfer berhasil:

  1. Membaca file dalam JavaScript menggunakan File API.
  2. Buat koneksi pembanding antara klien dengan RTCPeerConnection.
  3. Buat saluran data antarklien dengan RTCDataChannel.

Ada beberapa poin yang perlu dipertimbangkan saat mencoba mengirim file melalui RTCDataChannel:

  • Ukuran file: jika ukuran file cukup kecil dan dapat disimpan serta dimuat sebagai satu Blob, Anda dapat memuat ke dalam memori menggunakan File API, lalu mengirim file melalui saluran yang andal sebagaimana adanya (meskipun perlu diingat bahwa browser akan menetapkan batas ukuran transfer maksimum). Seiring bertambahnya ukuran file, segalanya menjadi semakin rumit. Saat mekanisme pemotongan diperlukan, potongan file akan dimuat dan dikirim ke peer lain, disertai dengan metadata chunkID sehingga peer dapat mengenalinya. Perhatikan bahwa dalam kasus ini, Anda juga perlu menyimpan potongan terlebih dahulu ke penyimpanan offline (misalnya, menggunakan FileSystem API) dan menyimpannya ke disk pengguna hanya ketika Anda memiliki file secara keseluruhan.
  • Ukuran potongan: ini adalah "atom" data terkecil untuk aplikasi Anda. Chunking diperlukan karena saat ini ada batas ukuran pengiriman (meskipun hal ini akan diperbaiki dalam versi saluran data mendatang). Rekomendasi saat ini untuk ukuran potongan maksimum adalah 64 KiB.

Setelah file ditransfer sepenuhnya ke sisi lain, file dapat didownload menggunakan tag anchor:

function saveFile(blob) {
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = 'File Name';
  link.click();
};

Aplikasi berbagi file di PubShare dan GitHub ini menggunakan teknik ini. Keduanya merupakan open source dan memberikan dasar yang baik untuk aplikasi berbagi file berbasis RTCDataChannel.

Jadi, apa yang dapat Anda lakukan?

RTCDataChannel membuka pintu bagi cara baru untuk membuat aplikasi bagi berbagi file, game multiplayer, dan penayangan konten.

  • Berbagi file peer-to-peer seperti yang dijelaskan sebelumnya
  • Game multiplayer, yang dipasangkan dengan teknologi lain, seperti WebGL, seperti yang terlihat dalam BananaBread Mozilla
  • Penayangan konten diciptakan kembali oleh PeerCDN, framework yang memberikan aset web melalui komunikasi data secara peer-to-peer

Mengubah cara membangun aplikasi

Anda kini dapat menyediakan aplikasi yang lebih menarik menggunakan koneksi berperforma tinggi dan latensi rendah melalui RTCDataChannel. Framework, seperti PeerJS dan PubNub WebRTC SDK, membuat RTCDataChannel lebih mudah diimplementasikan dan API ini kini memiliki dukungan yang luas di seluruh platform.

Hadirnya RTCDataChannel dapat mengubah cara Anda berpikir tentang transfer data di browser.

Cari tahu selengkapnya