Menggunakan WebTransport

WebTransport adalah API yang menawarkan pengiriman pesan server klien dan berlatensi rendah dua arah. Pelajari lebih lanjut kasus penggunaannya, dan cara memberikan masukan tentang masa depan penerapan tersebut.

Latar belakang

Apa itu WebTransport?

WebTransport adalah API web yang menggunakan protokol HTTP/3 sebagai transportasi dua arah. Hal ini dimaksudkan untuk komunikasi dua arah antara klien web dan server HTTP/3. API ini mendukung pengiriman data secara tidak dapat diandalkan melalui API datagram, dan secara andal melalui API stream.

Datagram ideal untuk mengirim dan menerima data yang tidak memerlukan jaminan pengiriman yang kuat. Setiap paket data dibatasi ukurannya oleh unit transmisi maksimum (MTU) koneksi yang mendasarinya, dan mungkin atau mungkin tidak berhasil dikirim, dan jika ditransfer, paket tersebut dapat tiba dalam urutan arbitrer. Karakteristik ini membuat API datagram ideal untuk transmisi data dengan upaya terbaik dan latensi rendah. Anda dapat menganggap datagram sebagai pesan protokol datagram pengguna (UDP), tetapi dienkripsi dan dikontrol oleh kemacetan.

Sebaliknya, API aliran data menyediakan transfer data yang diurutkan dan andal. Jenis data ini sangat cocok untuk skenario di mana Anda perlu mengirim atau menerima satu atau beberapa aliran data yang diurutkan. Menggunakan beberapa streaming WebTransport serupa dengan membuat beberapa koneksi TCP, tetapi karena HTTP/3 menggunakan protokol QUIC yang lebih ringan pada prinsipnya, stream tersebut dapat dibuka dan ditutup tanpa memerlukan banyak overhead.

Kasus penggunaan

Ini adalah daftar kecil kemungkinan cara developer menggunakan WebTransport.

  • Mengirim status game pada interval reguler dengan latensi minimal ke server melalui pesan kecil, tidak dapat diandalkan, tidak berurutan.
  • Menerima streaming media yang dikirim dari server dengan latensi minimal, terlepas dari aliran data lainnya.
  • Menerima notifikasi yang dikirim dari server saat halaman web terbuka.

Kami tertarik untuk mendengarkan lebih lanjut rencana Anda dalam menggunakan WebTransport.

Dukungan browser

Dukungan Browser

  • 97
  • 97
  • 114
  • x

Sumber

Seperti semua fitur yang tidak memiliki dukungan browser universal, coding secara defensif melalui deteksi fitur adalah praktik terbaik.

Status saat ini

Langkah Status
1. Buat pesan penjelasan Selesai
2. Membuat draf awal spesifikasi Selesai
3. Mengumpulkan masukan dan mengulangi desain Selesai
4. Uji coba origin Selesai
5. Peluncuran Chromium 97

Hubungan WebTransport dengan teknologi lain

Apakah WebTransport adalah pengganti WebSockets?

Mungkin. Ada kasus penggunaan yang mana WebSockets atau WebTransport mungkin merupakan protokol komunikasi yang valid untuk digunakan.

Komunikasi WebSocket dimodelkan berdasarkan aliran pesan tunggal yang andal dan teratur, yang cocok untuk beberapa jenis kebutuhan komunikasi. Jika Anda memerlukan karakteristik tersebut, API aliran WebTransport juga dapat menyediakannya. Sebagai perbandingan, datagram API WebTransport menyediakan pengiriman latensi rendah, tanpa jaminan keandalan atau pemesanan, sehingga bukan pengganti langsung untuk WebSockets.

Dengan menggunakan WebTransport, melalui API datagram atau melalui beberapa instance Streams API serentak, Anda tidak perlu mengkhawatirkan pemblokiran head-of-line yang dapat menjadi masalah pada WebSockets. Selain itu, ada manfaat performa saat membuat koneksi baru, karena QUIC handshake yang mendasarinya lebih cepat daripada memulai TCP melalui TLS.

WebTransport adalah bagian dari spesifikasi draf baru, sehingga ekosistem WebSocket di seputar library klien dan server saat ini jauh lebih tangguh. Jika Anda memerlukan sesuatu yang dapat langsung berfungsi dengan penyiapan server umum, dan dengan dukungan klien web yang luas, WebSockets adalah pilihan yang lebih baik saat ini.

Apakah WebTransport sama dengan UDP Socket API?

Tidak. WebTransport bukan UDP Socket API. Meskipun WebTransport menggunakan HTTP/3, yang menggunakan UDP "di balik layar", WebTransport memiliki persyaratan seputar enkripsi dan kontrol kemacetan yang membuatnya lebih dari sekadar UDP Socket API dasar.

Apakah WebTransport adalah alternatif untuk saluran data WebRTC?

Ya, untuk koneksi klien-server. WebTransport memiliki banyak properti yang sama dengan saluran data WebRTC, meskipun protokol yang mendasarinya berbeda.

Umumnya, menjalankan server yang kompatibel dengan HTTP/3 memerlukan lebih sedikit penyiapan dan konfigurasi daripada mempertahankan server WebRTC, yang melibatkan pemahaman beberapa protokol (ICE, DTLS, dan SCTP) untuk mendapatkan transport yang berfungsi. WebRTC memerlukan banyak hal bergerak yang dapat menyebabkan kegagalan negosiasi klien/server.

WebTransport API dirancang dengan mempertimbangkan kasus penggunaan developer web, dan akan terasa lebih seperti menulis kode platform web modern daripada menggunakan antarmuka saluran data WebRTC. Tidak seperti WebRTC, WebTransport didukung di dalam Web Worker, yang memungkinkan Anda melakukan komunikasi klien-server secara terpisah dari halaman HTML tertentu. Karena WebTransport menampilkan antarmuka yang sesuai dengan Streams, WebTransport mendukung pengoptimalan terkait tekanan balik.

Namun, jika Anda sudah memiliki penyiapan klien/server WebRTC yang berfungsi dan sesuai dengan keinginan Anda, beralih ke WebTransport mungkin tidak memberikan banyak keuntungan.

Cobalah

Cara terbaik untuk bereksperimen dengan WebTransport adalah dengan memulai server HTTP/3 yang kompatibel. Selanjutnya, Anda dapat menggunakan halaman ini dengan klien JavaScript dasar untuk mencoba komunikasi klien/server.

Selain itu, server echo yang dikelola komunitas tersedia di webtransport.day.

Menggunakan API

WebTransport dirancang di atas dasar platform web modern, seperti Streams API. Fitur ini sangat bergantung pada promise, dan berfungsi baik dengan async dan await.

Implementasi WebTransport saat ini di Chromium mendukung tiga jenis traffic yang berbeda: datagram, serta aliran searah dan dua arah.

Menghubungkan ke server

Anda dapat terhubung ke server HTTP/3 dengan membuat instance WebTransport. Skema URL harus https. Anda harus menentukan nomor port secara eksplisit.

Anda harus menggunakan promise ready untuk menunggu koneksi dibuat. Promise ini tidak akan dipenuhi hingga penyiapan selesai, dan akan ditolak jika koneksi gagal pada tahap QUIC/TLS.

Promise closed terpenuhi saat koneksi ditutup secara normal, dan menolak jika penutupan tidak terduga.

Jika server menolak koneksi karena error indikasi klien (misalnya, jalur URL tidak valid), hal tersebut akan menyebabkan closed ditolak, sementara ready tetap belum terselesaikan.

const url = 'https://example.com:4999/foo/bar';
const transport = new WebTransport(url);

// Optionally, set up functions to respond to
// the connection closing:
transport.closed.then(() => {
  console.log(`The HTTP/3 connection to ${url} closed gracefully.`);
}).catch((error) => {
  console.error(`The HTTP/3 connection to ${url} closed due to ${error}.`);
});

// Once .ready fulfills, the connection can be used.
await transport.ready;

Datagram API

Setelah memiliki instance WebTransport yang terhubung ke server, Anda dapat menggunakannya untuk mengirim dan menerima bit data terpisah, yang dikenal sebagai datagram.

Pengambil writeable menampilkan WritableStream, yang dapat digunakan klien web untuk mengirim data ke server. Pengambil readable menampilkan ReadableStream, yang memungkinkan Anda memproses data dari server. Kedua aliran data pada dasarnya tidak dapat diandalkan, sehingga ada kemungkinan data yang Anda tulis tidak akan diterima oleh server, begitu pula sebaliknya.

Kedua jenis aliran data menggunakan instance Uint8Array untuk transfer data.

// Send two datagrams to the server.
const writer = transport.datagrams.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);

// Read datagrams from the server.
const reader = transport.datagrams.readable.getReader();
while (true) {
  const {value, done} = await reader.read();
  if (done) {
    break;
  }
  // value is a Uint8Array.
  console.log(value);
}

Streams API

Setelah terhubung ke server, Anda juga dapat menggunakan WebTransport untuk mengirim dan menerima data melalui Streams API-nya.

Setiap bagian dari semua aliran data adalah Uint8Array. Tidak seperti Datagram API, stream ini dapat diandalkan. Namun, setiap aliran data bersifat independen, sehingga urutan data di berbagai aliran data tidak dijamin.

WebTransportSendStream

WebTransportSendStream dibuat oleh klien web menggunakan metode createUnidirectionalStream() dari instance WebTransport, yang menampilkan promise untuk WebTransportSendStream.

Gunakan metode close() dari WritableStreamDefaultWriter untuk menutup koneksi HTTP/3 terkait. Browser akan mencoba mengirim semua data yang tertunda sebelum benar-benar menutup koneksi terkait.

// Send two Uint8Arrays to the server.
const stream = await transport.createUnidirectionalStream();
const writer = stream.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);
try {
  await writer.close();
  console.log('All data has been sent.');
} catch (error) {
  console.error(`An error occurred: ${error}`);
}

Demikian pula, gunakan metode abort() dari WritableStreamDefaultWriter untuk mengirim RESET\_STREAM ke server. Saat menggunakan abort(), browser dapat menghapus data tertunda yang belum dikirim.

const ws = await transport.createUnidirectionalStream();
const writer = ws.getWriter();
writer.write(...);
writer.write(...);
await writer.abort();
// Not all the data may have been written.

WebTransportReceiveStream

WebTransportReceiveStream dimulai oleh server. Mendapatkan WebTransportReceiveStream adalah proses dua langkah untuk klien web. Pertama, fungsi ini memanggil atribut incomingUnidirectionalStreams dari instance WebTransport, yang menampilkan ReadableStream. Setiap bagian dari ReadableStream tersebut, nantinya, adalah WebTransportReceiveStream yang dapat digunakan untuk membaca instance Uint8Array yang dikirim oleh server.

async function readFrom(receiveStream) {
  const reader = receiveStream.readable.getReader();
  while (true) {
    const {done, value} = await reader.read();
    if (done) {
      break;
    }
    // value is a Uint8Array
    console.log(value);
  }
}

const rs = transport.incomingUnidirectionalStreams;
const reader = rs.getReader();
while (true) {
  const {done, value} = await reader.read();
  if (done) {
    break;
  }
  // value is an instance of WebTransportReceiveStream
  await readFrom(value);
}

Anda dapat mendeteksi penutupan aliran menggunakan promise closed dari ReadableStreamDefaultReader. Saat koneksi HTTP/3 yang mendasarinya ditutup dengan bit FIN, promise closed terpenuhi setelah semua data dibaca. Jika koneksi HTTP/3 ditutup tiba-tiba (misalnya, oleh RESET\_STREAM), promise closed akan ditolak.

// Assume an active receiveStream
const reader = receiveStream.readable.getReader();
reader.closed.then(() => {
  console.log('The receiveStream closed gracefully.');
}).catch(() => {
  console.error('The receiveStream closed abruptly.');
});

WebTransportBidirectionalStream

WebTransportBidirectionalStream mungkin dibuat oleh server atau klien.

Klien web dapat membuatnya menggunakan metode createBidirectionalStream() dari instance WebTransport, yang menampilkan promise untuk WebTransportBidirectionalStream.

const stream = await transport.createBidirectionalStream();
// stream is a WebTransportBidirectionalStream
// stream.readable is a ReadableStream
// stream.writable is a WritableStream

Anda dapat memproses WebTransportBidirectionalStream yang dibuat oleh server dengan atribut incomingBidirectionalStreams dari instance WebTransport, yang menampilkan ReadableStream. Setiap bagian dari ReadableStream tersebut akan merupakan WebTransportBidirectionalStream.

const rs = transport.incomingBidirectionalStreams;
const reader = rs.getReader();
while (true) {
  const {done, value} = await reader.read();
  if (done) {
    break;
  }
  // value is a WebTransportBidirectionalStream
  // value.readable is a ReadableStream
  // value.writable is a WritableStream
}

WebTransportBidirectionalStream hanyalah kombinasi dari WebTransportSendStream dan WebTransportReceiveStream. Contoh dari dua bagian sebelumnya menjelaskan cara menggunakan masing-masing bagian.

Contoh lainnya

Spesifikasi draf WebTransport mencakup sejumlah contoh inline tambahan, beserta dokumentasi lengkap untuk semua metode dan properti.

WebTransport di DevTools Chrome

Sayangnya, Chrome DevTools saat ini tidak mendukung WebTransport. Anda dapat "memberi bintang" pada masalah Chrome ini untuk mendapatkan notifikasi tentang update di antarmuka DevTools.

Isi Ulang

Polyfill (atau lebih tepatnya ponyfill yang menyediakan fungsi sebagai modul mandiri yang dapat Anda gunakan) disebut webtransport-ponyfill-websocket, yang mengimplementasikan beberapa fitur WebTransport tersedia. Baca batasan dalam README project dengan cermat untuk menentukan apakah solusi ini dapat berfungsi untuk kasus penggunaan Anda atau tidak.

Pertimbangan privasi dan keamanan

Lihat bagian yang sesuai dari spesifikasi draf untuk mendapatkan panduan yang kredibel.

Masukan

Tim Chrome ingin mengetahui pendapat dan pengalaman Anda menggunakan API ini.

Masukan tentang desain API

Apakah ada sesuatu pada API yang aneh atau tidak berfungsi seperti yang diharapkan? Atau apakah ada bagian yang hilang yang diperlukan untuk menerapkan ide Anda?

Laporkan masalah di repo GitHub Web Transport, atau tambahkan pendapat Anda ke masalah yang sudah ada.

Ada masalah dengan penerapan?

Apakah Anda menemukan bug pada implementasi Chrome?

Laporkan bug di https://new.crbug.com. Sertakan detail sebanyak mungkin, beserta petunjuk sederhana untuk mereproduksi.

Berencana menggunakan API?

Dukungan publik Anda membantu Chrome memprioritaskan fitur, dan menunjukkan kepada vendor browser lainnya betapa pentingnya mendukung fitur tersebut.

Diskusi umum

Anda dapat menggunakan Google Grup web-transport-dev untuk menjawab pertanyaan atau menyelesaikan soal umum yang tidak sesuai dengan salah satu kategori lainnya.

Ucapan terima kasih

Artikel ini berisi informasi dari WebTransport Explainer, spesifikasi draf, dan dokumen desain terkait. Terima kasih kepada masing-masing penulis yang telah memberikan yayasan tersebut.

Banner besar di postingan ini adalah Robin Pierre di Unsplash.