Dipublikasikan: 8 Juni 2020
WebTransport adalah API web yang menggunakan protokol HTTP/3 sebagai transport dua arah. Tindakan ini ditujukan untuk komunikasi dua arah antara klien web dan server HTTP/3. API ini mendukung pengiriman data yang tidak andal dengan datagram API, dan pengiriman data yang andal dengan streams API.
Datagram ideal untuk mengirim dan menerima data yang tidak memerlukan jaminan pengiriman yang kuat. Ukuran setiap paket data dibatasi oleh unit transmisi maksimum (MTU) koneksi yang mendasarinya, dan mungkin berhasil atau tidak berhasil ditransmisikan, dan jika ditransfer, paket tersebut mungkin tiba dalam urutan yang acak. Karakteristik ini menjadikan 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 kemacetannya.
Sebaliknya, API streaming menyediakan transfer data yang andal dan berurutan. Aliran data ini sangat cocok untuk skenario saat Anda perlu mengirim atau menerima satu atau beberapa aliran data yang berurutan. Menggunakan beberapa stream WebTransport sama dengan membuat beberapa koneksi TCP, tetapi karena HTTP/3 menggunakan protokol QUIC yang lebih ringan di balik layar, stream dapat dibuka dan ditutup tanpa banyak overhead.
Kasus penggunaan
Berikut adalah daftar kecil kemungkinan cara developer menggunakan WebTransport.
- Mengirim status game pada interval reguler dengan latensi minimal ke server dalam pesan kecil, tidak andal, dan tidak berurutan.
- Menerima aliran media yang didorong dari server dengan latensi minimal, terlepas dari aliran data lainnya.
- Menerima notifikasi yang dikirim dari server saat halaman web terbuka.
Kami ingin mendengar lebih lanjut tentang rencana Anda menggunakan WebTransport.
Dukungan browser
Seperti semua fitur yang tidak memiliki dukungan browser universal, sebaiknya tambahkan deteksi fitur.
Hubungan dengan teknologi lain
Apakah WebTransport pengganti WebSocket?
Mungkin. Ada kasus penggunaan di mana WebSockets atau WebTransport mungkin merupakan protokol komunikasi yang valid untuk digunakan.
Komunikasi WebSockets dimodelkan di sekitar aliran pesan tunggal, andal, dan berurutan, 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 latensi rendah, tanpa jaminan keandalan atau pengurutan, sehingga bukan pengganti langsung WebSockets.
Saat menggunakan WebTransport, dengan API datagram atau beberapa instance API Stream serentak, Anda tidak perlu khawatir tentang pemblokiran head-of-line, yang dapat menjadi masalah dengan WebSockets. 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, dan dengan demikian ekosistem WebSocket di sekitar library klien dan server jauh lebih andal. Jika Anda memerlukan sesuatu yang berfungsi "langsung" 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 pada gilirannya menggunakan UDP "di balik layar", WebTransport memiliki persyaratan terkait enkripsi dan kontrol kemacetan yang menjadikannya lebih dari sekadar API Soket UDP dasar.
Apakah WebTransport merupakan alternatif untuk saluran data WebRTC?
Ya, untuk koneksi klien-server. WebTransport memiliki banyak properti yang sama dengan channel data WebRTC, meskipun protokol yang mendasarinya berbeda.
Secara umum, menjalankan server yang kompatibel dengan HTTP/3 memerlukan lebih sedikit penyiapan dan konfigurasi daripada memelihara server WebRTC, yang melibatkan pemahaman tentang beberapa protokol (ICE, DTLS, dan SCTP) untuk mendapatkan transport yang berfungsi. WebRTC melibatkan lebih banyak komponen bergerak yang dapat menyebabkan negosiasi klien/server gagal.
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 Workers, yang memungkinkan Anda melakukan komunikasi klien-server secara independen dari halaman HTML tertentu. Karena WebTransport mengekspos antarmuka yang kompatibel dengan Streams, WebTransport mendukung pengoptimalan seputar backpressure.
Namun, jika Anda sudah memiliki penyiapan klien/server WebRTC yang berfungsi dan Anda puas dengannya, beralih ke WebTransport mungkin tidak menawarkan banyak keuntungan.
Eksperimen
Cara terbaik untuk bereksperimen dengan WebTransport adalah dengan memulai server HTTP/3 yang kompatibel. Gunakan halaman ini dengan klien JavaScript dasar untuk mencoba komunikasi klien dan server.
Selain itu, server echo yang dikelola komunitas tersedia di webtransport.day.
Menggunakan API
WebTransport didesain di atas primitif platform web modern, seperti Streams API. API ini sangat mengandalkan promise, dan berfungsi dengan baik dengan async dan await.
Implementasi WebTransport saat ini di Chromium mendukung tiga jenis traffic yang berbeda: datagram, serta aliran satu arah dan dua arah.
Menghubungkan ke server
Anda dapat terhubung ke server HTTP/3 dengan membuat instance WebTransport. Skema URL harus berupa https. Anda harus menentukan nomor port secara eksplisit.
Anda harus menggunakan promise ready untuk menunggu koneksi dibuat.
Janji ini tetap tidak terpenuhi hingga penyiapan selesai, dan ditolak jika
koneksi gagal pada tahap QUIC/TLS.
Janji closed terpenuhi saat koneksi ditutup secara normal, dan ditolak jika penutupan tidak terduga.
Jika server menolak koneksi karena error indikasi klien (seperti jalur URL tidak valid), maka hal itu menyebabkan closed ditolak, sementara ready tetap tidak 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 diskret, 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 pada dasarnya tidak dapat diandalkan, sehingga data yang Anda tulis mungkin tidak diterima oleh server, dan sebaliknya.
Kedua jenis aliran 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, aliran 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 aliran HTTP/3 terkait. Browser mencoba mengirim semua data yang tertunda sebelum benar-benar menutup aliran 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
Server memulai WebTransportReceiveStream.
Mendapatkan WebTransportReceiveStream adalah proses dua langkah untuk klien web. Pertama, klien memanggil atribut incomingUnidirectionalStreams instance WebTransport, yang menampilkan ReadableStream. Setiap bagian 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 menggunakan promise closed dari ReadableStreamDefaultReader. Jika streaming HTTP/3 yang mendasarinya ditutup dengan bit FIN, janji closed akan dipenuhi setelah semua data dibaca. Jika aliran HTTP/3 ditutup secara tiba-tiba (misalnya, oleh RESET_STREAM), maka janji 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 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 WebTransportSendStream dan WebTransportReceiveStream. Contoh dari dua bagian sebelumnya menjelaskan cara menggunakan masing-masingnya.
Polyfill
Tersedia polyfill (atau lebih tepatnya ponyfill yang menyediakan fungsi sebagai modul mandiri yang dapat Anda gunakan) yang disebut
webtransport-ponyfill-websocket
yang menerapkan beberapa fitur WebTransport. Baca batasan dalam
README project dengan cermat untuk menentukan apakah solusi ini dapat berfungsi untuk kasus penggunaan Anda.
Pertimbangan privasi dan keamanan
Lihat bagian yang sesuai dalam draf spesifikasi untuk mendapatkan panduan resmi.
Masukan
Apakah ada sesuatu tentang API yang tidak nyaman atau tidak berfungsi seperti yang diharapkan? Atau apakah ada bagian yang hilang yang perlu Anda terapkan untuk mewujudkan ide Anda?
- Laporkan masalah di repo GitHub Web Transport, atau tambahkan pendapat Anda ke masalah yang ada.
- Laporkan bug tentang penerapan Chromium. Sertakan detail sebanyak mungkin, beserta petunjuk untuk mereproduksi.
Dukungan publik Anda membantu Chrome memprioritaskan fitur, dan menunjukkan kepada vendor browser lain betapa pentingnya dukungan untuk fitur tersebut.
- Tweet @ChromiumDev menggunakan hashtag
#WebTransportdan detail tentang tempat dan cara Anda menggunakannya.
Diskusi umum
Anda dapat menggunakan Grup Google web-transport-dev untuk pertanyaan atau masalah umum yang tidak termasuk dalam salah satu kategori lainnya.
Ucapan terima kasih
Kami menggabungkan informasi dari Penjelasan WebTransport dan draf spesifikasi. Terima kasih kepada penulis yang bersangkutan karena telah memberikan dasar tersebut.