Menggunakan WebTransport

WebTransport adalah API yang menawarkan pesan klien-server dua arah dengan latensi rendah. Pelajari lebih lanjut kasus penggunaannya, dan cara memberikan masukan tentang masa depan penerapannya.

WebTransport adalah API web yang menggunakan protokol HTTP/3 sebagai transpor dua arah. Protokol ini ditujukan untuk komunikasi dua arah antara klien web dan server HTTP/3. API ini mendukung pengiriman data secara tidak andal melalui datagram API, dan secara andal melalui stream API.

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 berhasil atau tidak berhasil dikirim, dan jika ditransfer, paket tersebut mungkin tiba dalam urutan arbitrer. Karakteristik ini membuat API datagram ideal untuk transmisi data dengan latensi rendah dan upaya terbaik. Anda dapat menganggap datagram sebagai pesan user datagram protocol (UDP), tetapi dienkripsi dan dikontrol kemacetan.

Sebaliknya, API aliran data menyediakan transfer data yang andal dan teratur. Fungsi ini cocok untuk skenario saat Anda perlu mengirim atau menerima satu atau beberapa aliran data yang diurutkan. Menggunakan beberapa aliran WebTransport sama dengan membuat beberapa koneksi TCP, tetapi karena HTTP/3 menggunakan protokol QUIC yang lebih ringan di balik layar, koneksi tersebut dapat dibuka dan ditutup tanpa overhead yang terlalu besar.

Kasus penggunaan

Berikut 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, dan tidak berurutan.
  • Menerima streaming media yang didorong dari server dengan latensi minimal, terlepas dari streaming data lainnya.
  • Menerima notifikasi yang dikirim dari server saat halaman web terbuka.

Kami ingin mendengar lebih lanjut tentang rencana Anda menggunakan WebTransport.

Dukungan browser

Dukungan Browser

  • Chrome: 97.
  • Edge: 97.
  • Firefox: 114.
  • Safari: tidak didukung.

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. Membuat penjelasan Selesai
2. Membuat draf awal spesifikasi Selesai
3. Mengumpulkan masukan dan melakukan iterasi desain Selesai
4. Uji coba origin Selesai
5. Peluncuran Chromium 97

Hubungan WebTransport dengan teknologi lain

Apakah WebTransport adalah pengganti WebSocket?

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

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

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

WebTransport adalah bagian dari spesifikasi draf baru, sehingga ekosistem WebSocket di sekitar library klien dan server saat ini jauh lebih andal. Jika Anda memerlukan sesuatu yang berfungsi "secara otomatis" dengan penyiapan server umum, dan dengan dukungan klien web yang luas, WebSocket 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 pada akhirnya menggunakan UDP "di balik layar", WebTransport memiliki persyaratan seputar enkripsi dan kontrol kemacetan yang membuatnya lebih dari sekadar UDP Socket API dasar.

Apakah WebTransport merupakan 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 mengelola server WebRTC, yang melibatkan pemahaman beberapa protokol (ICE, DTLS, dan SCTP) untuk mendapatkan transpor yang berfungsi. WebRTC memerlukan lebih banyak bagian 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 independen dari halaman HTML tertentu. Karena mengekspos antarmuka yang sesuai dengan Aliran Data, WebTransport mendukung pengoptimalan seputar tekanan balik.

Namun, jika Anda sudah memiliki penyiapan klien/server WebRTC yang berfungsi dan memuaskan, beralih ke WebTransport mungkin tidak menawarkan banyak keuntungan.

Cobalah

Cara terbaik untuk bereksperimen dengan WebTransport adalah dengan memulai server HTTP/3 yang kompatibel. Kemudian, 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 primitif platform web modern, seperti Streams API. Fungsi ini sangat bergantung pada promise, dan berfungsi dengan baik dengan async dan await.

Implementasi WebTransport saat ini di Chromium mendukung tiga jenis traffic yang berbeda: datagram, serta aliran data satu arah 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 terpenuhi hingga penyiapan selesai, dan akan ditolak jika koneksi gagal pada tahap QUIC/TLS.

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

Jika server menolak koneksi karena error indikasi klien (misalnya, jalur URL tidak valid), hal itu 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 datagrams.

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 tersebut pada dasarnya tidak dapat diandalkan, sehingga data yang Anda tulis mungkin tidak akan diterima oleh server, dan sebaliknya.

Kedua jenis streaming 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, streaming ini dapat diandalkan. Namun, setiap aliran data bersifat independen, sehingga urutan data di seluruh 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 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 yang 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, pada gilirannya, 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 data menggunakan promise closed dari ReadableStreamDefaultReader. Saat koneksi HTTP/3 yang mendasarinya ditutup dengan bit FIN, promise closed akan terpenuhi setelah semua data dibaca. Jika koneksi HTTP/3 ditutup secara 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 dapat 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, pada gilirannya, adalah 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.

Contoh lainnya

Spesifikasi draf WebTransport menyertakan 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" masalah Chrome ini untuk mendapatkan notifikasi tentang info terbaru di antarmuka DevTools.

Polyfill

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

Pertimbangan privasi dan keamanan

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

Masukan

Tim Chrome ingin mendengar pendapat dan pengalaman Anda saat menggunakan API ini.

Masukan tentang desain API

Apakah ada sesuatu tentang API yang canggung atau tidak berfungsi seperti yang diharapkan? Atau apakah ada bagian yang hilang yang Anda perlukan untuk menerapkan ide Anda?

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

Mengalami masalah dengan penerapan?

Apakah Anda menemukan bug pada penerapan Chrome?

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

Berencana untuk menggunakan API?

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

Diskusi umum

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

Ucapan terima kasih

Artikel ini menggabungkan informasi dari Penjelasan WebTransport, spesifikasi draf, dan dokumen desain terkait. Terima kasih kepada masing-masing penulis yang telah menyediakan dasar tersebut.

Gambar hero di postingan ini adalah karya Robin Pierre di Unsplash.