Mengirim data antar-browser dengan saluran data WebRTC

Mengirim data antar-browser untuk komunikasi, game, atau transfer file bisa menjadi proses yang cukup rumit. Anda harus menyiapkan dan membayar server untuk meneruskan 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 secara 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 yang Dikirim 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 - tidak ada server perantara dan lebih sedikit 'hop'.
  • RTCDataChannel menggunakan Stream Control Transmission Protocol (SCTP), yang memungkinkan pengiriman semantik pengiriman yang tidak urut dan konfigurasi pengiriman ulang yang dapat dikonfigurasi.

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

Peringatan: Sinyal, STUN, dan TURN

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

WebRTC mengatasi NAT dan firewall dengan:

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

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

Kemampuan

RTCDataChannel API mendukung serangkaian 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 membantu saat menangani transfer file dan game multipemain.

RTCDataChannel dapat berfungsi dalam mode tidak andal dan tidak teratur (analog dengan User Datagram Protocol atau UDP), mode andal dan teratur (analog dengan Transmission Control Protocol atau TCP), dan mode andal sebagian:

  • Mode andal dan teratur menjamin transmisi pesan serta urutan pengirimannya. Hal ini memerlukan overhead tambahan, sehingga berpotensi membuat mode ini lebih lambat.
  • Mode yang tidak dapat diandalkan dan tidak berurutan tidak menjamin setiap pesan akan sampai ke sisi lain atau bagaimana urutannya. Hal ini akan menghilangkan overhead, sehingga mode ini dapat berfungsi jauh lebih cepat.
  • Mode andal parsial menjamin transmisi pesan dalam kondisi tertentu, seperti waktu tunggu pengiriman ulang atau jumlah maksimum pengiriman ulang. Urutan pesan juga dapat dikonfigurasi.

Performa untuk dua mode pertama hampir sama jika tidak ada kehilangan paket. Namun, dalam mode andal dan teratur, paket yang hilang menyebabkan paket lain diblokir di belakangnya, dan paket yang hilang mungkin menjadi usang pada saat paket tersebut ditransmisikan ulang dan tiba. Tentu saja, Anda dapat menggunakan beberapa saluran data dalam aplikasi yang sama, masing-masing dengan semantik yang andal atau tidak dapat diandalkan.

Berikut adalah tabel yang berguna dari High Performance Browser Networking oleh Ilya Grigorik:

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

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

Mengonfigurasi saluran data

Ada beberapa demo sederhana RTCDataChannel online:

Dalam contoh ini, browser membuat koneksi peer ke dirinya sendiri, lalu membuat saluran data dan mengirim pesan melalui koneksi peer. Kemudian, aplikasi ini membuat saluran data dan mengirim pesan melalui koneksi peer. Terakhir, pesan Anda muncul di kotak di sisi lain halaman!

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 dibuat. Peristiwa ini dapat dibuat sebelum atau setelah sinyal terjadi. Kemudian, Anda meneruskan label untuk membedakan saluran ini dari saluran lain dan serangkaian setelan konfigurasi opsional:

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

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

  • ordered: apakah saluran data harus menjamin urutan atau tidak
  • maxPacketLifeTime: waktu maksimum untuk mencoba dan mengirim ulang pesan yang gagal
  • maxRetransmits: jumlah maksimum upaya untuk mencoba dan mengirim ulang pesan yang gagal
  • protocol: memungkinkan subprotokol digunakan, yang memberikan informasi meta ke aplikasi
  • negotiated: jika ditetapkan ke benar, akan menghapus penyiapan otomatis saluran data di peer lain, sehingga memberikan 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 negotiated yang ditetapkan ke true)

Satu-satunya opsi yang perlu digunakan sebagian besar orang adalah tiga opsi pertama: ordered, maxPacketLifeTime, dan maxRetransmits. Dengan SCTP (sekarang digunakan oleh semua browser yang mendukung WebRTC), andal dan teratur disetel ke benar secara default. Sebaiknya gunakan tidak dapat diandalkan dan tidak diurutkan jika Anda menginginkan kontrol penuh dari lapisan aplikasi, tetapi dalam sebagian besar kasus, keandalan sebagian akan membantu.

Perlu diperhatikan bahwa, seperti dengan WebSocket, RTCDataChannel mengaktifkan peristiwa saat koneksi dibuat, ditutup, atau mengalami 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 aman seperti menggunakan koneksi berbasis SSL standar. DTLS distandarisasi dan di-build ke dalam semua browser yang mendukung WebRTC. Untuk informasi selengkapnya, lihat wiki Wireshark.

Mengubah cara Anda berpikir tentang data

Menangani data dalam jumlah besar bisa menjadi masalah di JavaScript. Seperti yang ditunjukkan oleh developer Sharefest, hal ini memerlukan cara baru untuk memikirkan data. Jika Anda mentransfer file yang lebih besar dari jumlah memori yang tersedia, Anda harus memikirkan cara baru untuk menyimpan informasi ini. Di sinilah teknologi, seperti FileSystem API, akan berperan, seperti yang akan Anda lihat selanjutnya.

Mem-build aplikasi berbagi file

Membuat aplikasi web yang dapat membagikan 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 untuk terhubung ke beberapa klien untuk berbagi yang lebih cepat, menjadikan fitur berbagi file WebRTC sebagai kandidat kuat untuk web.

Beberapa langkah diperlukan agar transfer berhasil:

  1. Baca file dalam JavaScript menggunakan File API.
  2. Buat koneksi peer antara klien dengan RTCPeerConnection.
  3. Buat saluran data antar-klien dengan RTCDataChannel.

Ada beberapa hal 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 file ke dalam memori menggunakan File API, lalu mengirim file melalui saluran yang andal sebagaimana adanya (meskipun perlu diingat bahwa browser menetapkan batas pada ukuran transfer maksimum). Seiring ukuran file yang semakin besar, hal-hal menjadi lebih rumit. Jika mekanisme pengelompokan diperlukan, potongan file akan dimuat dan dikirim ke peer lain, disertai dengan metadata chunkID agar 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 jika Anda memiliki file tersebut secara keseluruhan.
  • Ukuran bagian: ini adalah "atom" data terkecil untuk aplikasi Anda. Pembagian menjadi beberapa bagian diperlukan karena saat ini ada batas ukuran pengiriman (meskipun hal ini akan diperbaiki di versi saluran data mendatang). Rekomendasi saat ini untuk ukuran potongan maksimum adalah 64KiB.

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 ini di PubShare dan GitHub menggunakan teknik ini. Keduanya bersifat open source dan memberikan dasar yang baik untuk aplikasi berbagi file berdasarkan RTCDataChannel.

Jadi, apa yang dapat Anda lakukan?

RTCDataChannel membuka pintu bagi cara baru dalam membangun aplikasi untuk berbagi file, game multiplayer, dan pengiriman konten.

  • Berbagi file peer-to-peer seperti yang dijelaskan sebelumnya
  • Game multiplayer, yang disambungkan dengan teknologi lain, seperti WebGL, seperti yang terlihat di BananaBread Mozilla
  • Pengiriman konten yang diciptakan kembali oleh PeerCDN, framework yang mengirimkan aset web melalui komunikasi data peer-to-peer

Mengubah cara Anda membangun aplikasi

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

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

Cari tahu selengkapnya