Saluran Data QUIC: Langkah Pertama


Saluran Data berbasis QUIC dianggap sebagai alternatif untuk transportasi SCTP saat ini. Kelompok kerja Google WebRTC sudah bereksperimen dengan mereka:


Mari kita coba juga. Untuk melakukan ini, kami akan membuat aplikasi satu halaman yang mirip dengan contoh saluran WebRTC untuk mengirim teks - ini adalah contoh yang berfungsi penuh (tanpa server pemberi sinyal), yang, selanjutnya, akan memudahkan untuk membandingkan pendekatan dalam mengimplementasikan WebRTC DataChannels.

Sebelum kita mulai, mari kita mengingat kembali dasar-dasar DataChannel .

Secara singkat tentang DataChannel


DataChannels WebRTC memungkinkan peserta untuk bertukar data sewenang-wenang. Keduanya dapat diandalkan - yang sangat berguna saat mentransfer file - dan tidak dapat diandalkan, yang dapat diterima untuk informasi tentang posisi dalam gim. API adalah perpanjangan dari RTCPeerConnection dan terlihat seperti ini:

 const dc = pc.createDataChannel("some label string"); // ,    – ,   – //    send dc.send("some string"); //    otherPc.addEventListener('datachannel', e => { const channel = e.channel; channel.onmessage = event => { console.log('received', event.data); }); }); 

Pada halaman sampel WebRTC resmi ada contoh mengirim string dan data biner .

DataChannel menggunakan SCTP . Ini bekerja secara paralel dengan transport RTP untuk stream audio dan video. Tidak seperti UDP, yang biasanya digunakan oleh stream audio dan video, SCTP menawarkan banyak fitur lainnya, seperti saluran multiplexing melalui satu koneksi atau dapat diandalkan, sebagian dapat diandalkan (mis. Dapat diandalkan, tetapi tidak tertata) dan mode yang tidak dapat diandalkan.

Google memperkenalkan QUIC pada 2012 (lebih lanjut tentang sejarah protokol dan nuansanya dapat ditemukan di materi kami yang lain - catatan penerjemah). Seperti WebRTC, protokol QUIC juga telah diambil di bawah sayap IETF dan sekarang HTTP / 3 . QUIC memiliki sejumlah inovasi hebat, seperti: latensi berkurang, perhitungan bandwidth berdasarkan kontrol kemacetan, koreksi keterlambatan langsung (FEC) dan implementasi di ruang pengguna (bukan kernel) untuk pengguliran yang lebih cepat.

QUIC bisa menjadi alternatif untuk RTCP untuk WebRTC - seperti transportasi untuk DataChannel. Eksperimen saat ini berusaha menghindari penggunaan RTCPeerConnection API ( dan SDP! ) Dengan menggunakan versi terpisah dari transportasi ICE. Anggap saja sebagai koneksi virtual yang menambah sedikit keamanan dan banyak NAT traversal .

Dalam video di bawah ini, Ian Swett dari tim jejaring Chrome menjelaskan konsep ini. Dan meskipun pidato ini sudah berumur beberapa tahun, pidato ini masih memberikan informasi tambahan tentang topik tersebut:


Langkah pertama dengan QUIC


Untungnya, sebagian besar kode dari artikel 2015 tetap relevan dan mudah beradaptasi dengan API baru. Mari kita cari tahu.

Kloning kode dari sini atau coba di sini . Harap perhatikan bahwa Chrome (versi 73+ sekarang adalah Canary) harus dijalankan dengan tanda khusus agar eksperimen dapat berfungsi secara lokal:

 google-chrome-unstable --enable-blink-features=RTCQuicTransport,RTCIceTransportExtension 

Pengaturan Transport ICE


Spesifikasi RTCIceTransport didasarkan pada ORTC, sehingga pengaturannya mirip dengan kode lama:

 const ice1 = new RTCIceTransport(); ice1.onstatechange = function() { console.log('ICE transport 1 state change', ice1.state); }; const ice2 = new RTCIceTransport(); ice2.onstatechange = function() { console.log('ICE transport 2 state change', ice2.state); }; //  ICE- ice1.onicecandidate = function(evt) { console.log('1 -> 2', evt.candidate); if (evt.candidate) { ice2.addRemoteCandidate(evt.candidate); } }; ice2.onicecandidate = function(evt) { console.log('2 -> 1', evt.candidate); if (evt.candidate) { ice1.addRemoteCandidate(evt.candidate); } }; //  ICE- ice1.start(ice2.getLocalParameters(), 'controlling'); ice2.start(ice1.getLocalParameters(), 'controlled'); ice1.gather(iceOptions); ice2.gather(iceOptions); 

Perhatikan bahwa API ini tidak memiliki RTCIceGatherer, tidak seperti ORTC. Karena kami sudah memiliki semua yang kami butuhkan untuk menginstal transportasi ICE.

Mengkonfigurasi Transportasi QUIC


 const quic1 = new RTCQuicTransport(ice1); quic1.onstatechange = function() { console.log('QUIC transport 1 state change', quic1.state); }; const quic2 = new RTCQuicTransport(ice2); quic2.onstatechange = function() { console.log('QUIC transport 2 state change', quic2.state); }; //     QUIC quic2.addEventListener('quicstream', (e) => { console.log('QUIC transport 2 got a stream', e.stream); receiveStream = e.stream; }); 

Di sini, percobaan berangkat dari spesifikasi yang menggunakan otentikasi berbasis sertifikat. Sebagai gantinya, kunci publik digunakan, seperti yang dikatakan oleh posting Google Developers :
Koneksi RTCQuicTransport dikonfigurasi dengan kunci publik API. Kami saat ini tidak merencanakan untuk API ini untuk menggantikan validasi asli. Ini akan diganti dengan pensinyalan sertifikat jarak jauh untuk memvalidasi sertifikat yang ditandatangani sendiri - ketika QUIC mulai mendukungnya di Chromium.
Sejauh ini, sangat bagus.

QUICStream untuk mengirim dan menerima data


Menggunakan QUICStream sedikit lebih rumit daripada DataRhannel WebRTC. Streams API ( lihat detail tentang MDN ) yang dibuat oleh kelompok kerja WHATWG telah diterima tetapi tidak diterapkan .

Kami membuat sendStream hanya setelah transport QUIC masuk ke status "terhubung" - dalam kondisi yang berbeda ini akan menyebabkan kesalahan:

 quic1.onstatechange = function() { console.log('QUIC transport 1 state change', quic1.state); if (quic1.state === 'connected' && !sendStream) { sendStream = quic1.createStream('webrtchacks'); //   createDataChannel. document.getElementById('sendButton').disabled = false; document.getElementById('dataChannelSend').disabled = false; } }; 

Kemudian kami melampirkan penangan ke tombol kirim dan kolom input: setelah mengklik tombol, teks dari kolom input dikodekan dalam Uint8Array dan ditulis ke stream:

 document.getElementById('sendButton').onclick = () => { const rawData = document.getElementById('dataChannelSend').value; document.getElementById('dataChannelSend').value = ''; //  Uint8Array. ,       TextEncoder. const data = encoder.encode(rawData); sendStream.write({ data, }); }; 

Entri pertama akan memicu peristiwa onquicstream pada transport QUIC jarak jauh:

 //     QUIC quic2.addEventListener('quicstream', (e) => { console.log('QUIC transport 2 got a stream', e.stream); receiveStream = e.stream; receiveStream.waitForReadable(1) .then(ondata); }); 

... lalu kami menunggu data dapat dibaca:
 function ondata() { const buffer = new Uint8Array(receiveStream.readBufferedAmount); const res = receiveStream.readInto(buffer); const data = decoder.decode(buffer); document.getElementById('dataChannelReceive').value = data; receiveStream.waitForReadable(1) .then(ondata); } 

Semua data dari receiveStream akan dibaca, diterjemahkan ke dalam teks dan ditempatkan di bidang output. Dan setiap kali data yang dapat dibaca muncul.

Kesimpulan dan Komentar


Saya harap contoh ini lebih mudah dipahami daripada yang serupa di blog Google . Metode ini hampir tidak cocok untuk koneksi P2P, DataChannel pada SCTP sudah baik-baik saja untuk mereka. Namun, ini bisa menjadi alternatif yang menarik untuk soket web dengan server QUIC di ujung lainnya. Sampai ini terjadi, Anda harus menentukan cara yang layak untuk bekerja dengan saluran yang tidak dapat diandalkan dan tidak teratur. Menurut pendapat saya, saran dari posting tersebut lebih mirip hack daripada keputusan.

Juga tidak jelas umpan balik apa yang menunggu pengembang dari luar. "Perkenalkan spesifikasi, alih-alih mematung pintasan lagi, yang akan tetap bersama kami selama beberapa tahun," kedengarannya terlalu jelas. Plus, pendapat umum masyarakat cenderung menggunakan aliran WHATWG, yang membuat pengembang cahaya aneh meminta untuk menguji API mereka sendiri untuk membaca data.

Saya juga ingin SCTP di Chromium memiliki fitur tambahan. Misalnya, pertanyaan tentang DataChannel ini - yang berperingkat tertinggi, tetap - hampir tidak tersentuh selama tiga tahun. Tidak sepenuhnya jelas mengapa ada fokus pada QUIC ketika masih ada tugas SCTP; namun, ini tidak boleh menghentikan siapa pun dari pengujian QUIC dan umpan balik tentang hasilnya.

Komentar oleh Voximplant


Sebuah kata untuk irbisadm lead frontend kami:
Untuk waktu yang lama, SDK kami telah digunakan untuk memberi sinyal soket web. Ini adalah standar teruji waktu yang sangat baik, tetapi ada beberapa masalah dengannya. Yang pertama adalah TCP. Dan TCP tidak begitu bagus dan cepat di jaringan seluler, plus itu tidak mendukung roaming antar jaringan. Kedua, seringkali tekstual (ada mode biner juga, tetapi Anda jarang melihatnya).

Kami baru-baru ini meluncurkan uji beta tertutup dari protokol pensinyalan pada DataChannel. Protokol ini juga bukan tanpa minusnya, tetapi karena protokol ini bekerja di jaringan yang buruk dan saat roaming, protokol ini menaklukkan pada pandangan pertama. Sudahkah Anda mengubah jaringan? Tidak perlu membuat ulang koneksi. ICE Restart dalam banyak kasus akan membantu menemukan cara baru untuk lalu lintas. Tetapi, seperti yang saya katakan, protokol masih memiliki kelemahan: tidak semua browser mendukung semua ekstensi protokol, seperti pengiriman yang dijamin dan dukungan pesanan paket; juga protokol tidak mendukung gzip untuk mode teks di luar kotak. Tetapi semua masalah ini dapat diselesaikan di sisi aplikasi.

Source: https://habr.com/ru/post/id441168/


All Articles