WebTransport เป็น API ที่มีการรับส่งข้อความแบบไคลเอ็นต์-เซิร์ฟเวอร์แบบสองทิศทางที่มีเวลาในการตอบสนองต่ำ ดูข้อมูลเพิ่มเติมเกี่ยวกับกรณีการใช้งานและวิธีแสดงความคิดเห็นเกี่ยวกับการใช้งานในอนาคต
ฉากหลัง
WebTransport คืออะไร
WebTransport คือ Web API ที่ใช้โปรโตคอล HTTP/3 เป็นการรับส่งข้อมูลแบบ 2 ทาง โดยมีไว้สำหรับการสื่อสารแบบ 2 ทางระหว่างเว็บไคลเอ็นต์กับเซิร์ฟเวอร์ HTTP/3 โดยรองรับการส่งข้อมูลทั้งแบบไม่น่าเชื่อถือผ่าน API แบบ Datagram และแบบน่าเชื่อถือผ่าน API แบบสตรีม
ดาต้าแกรมเหมาะสำหรับการส่งและรับข้อมูลที่ไม่จำเป็นต้องมีการรับประกันการนำส่งที่เข้มงวด แพ็กเก็ตข้อมูลแต่ละรายการมีขนาดจำกัดตามหน่วยส่งสูงสุด (MTU) ของการเชื่อมต่อพื้นฐาน และอาจส่งสำเร็จหรือไม่ก็ได้ และหากมีการโอนข้อมูล แพ็กเก็ตอาจมาถึงตามลำดับใดก็ได้ ลักษณะเหล่านี้ทำให้ API ของ Datagram เหมาะอย่างยิ่งสำหรับการส่งข้อมูลที่มีเวลาในการตอบสนองต่ำและส่งข้อมูลอย่างเต็มที่ คุณอาจมองว่า Datagram เป็นข้อความUser Datagram Protocol (UDP) แต่มีการเข้ารหัสและควบคุมความแออัด
ในทางตรงกันข้าม API สตรีมจะให้การโอนข้อมูลที่เชื่อถือได้และมีการจัดลำดับ ซึ่งเหมาะกับสถานการณ์ที่คุณต้องส่งหรือรับสตรีมข้อมูลที่เรียงลำดับแล้วอย่างน้อย 1 รายการ การใช้สตรีม WebTransport หลายรายการจะคล้ายกับการสร้างการเชื่อมต่อ TCP หลายรายการ แต่เนื่องจาก HTTP/3 ใช้โปรโตคอล QUIC ที่มีน้ำหนักเบากว่าอยู่เบื้องหลัง จึงสามารถเปิดและปิดได้โดยไม่ต้องมีค่าใช้จ่ายมากนัก
กรณีการใช้งาน
นี่คือรายการเล็กๆ ของวิธีที่นักพัฒนาแอปอาจใช้ WebTransport
- การส่งสถานะเกมเป็นระยะๆ โดยมีเวลาในการตอบสนองน้อยที่สุดไปยังเซิร์ฟเวอร์ผ่านข้อความขนาดเล็กที่เชื่อถือไม่ได้และเรียงลำดับไม่ถูกต้อง
- รับสตรีมสื่อที่ส่งจากเซิร์ฟเวอร์โดยมีความหน่วงน้อยที่สุด โดยไม่ขึ้นอยู่กับสตรีมข้อมูลอื่นๆ
- รับการแจ้งเตือนที่พุชจากเซิร์ฟเวอร์ขณะที่หน้าเว็บเปิดอยู่
เรายินดีที่จะรับฟังเพิ่มเติมเกี่ยวกับวิธีที่คุณวางแผนที่จะใช้ WebTransport
การสนับสนุนเบราว์เซอร์
เช่นเดียวกับฟีเจอร์ทั้งหมดที่เบราว์เซอร์บางตัวไม่รองรับ การเขียนโค้ดแบบป้องกันผ่านการตรวจหาฟีเจอร์ถือเป็นแนวทางปฏิบัติแนะนำ
สถานะปัจจุบัน
ขั้นตอน | สถานะ |
---|---|
1. สร้างวิดีโออธิบาย | เสร็จสมบูรณ์ |
2. สร้างร่างข้อกำหนดเบื้องต้น | เสร็จสมบูรณ์ |
3. รวบรวมความคิดเห็นและออกแบบซ้ำ | เสร็จสมบูรณ์ |
4. ช่วงทดลองใช้จากต้นทาง | เสร็จสมบูรณ์ |
5. เปิดตัว | Chromium 97 |
ความสัมพันธ์ของ WebTransport กับเทคโนโลยีอื่นๆ
WebTransport ใช้แทน WebSocket ได้ไหม
อาจจะได้ มีกรณีการใช้งานที่ WebSockets หรือ WebTransport อาจเป็นโปรโตคอลการสื่อสารที่ถูกต้องในการใช้งาน
การสื่อสารผ่าน WebSocket ได้รับการออกแบบมาให้มีสตรีมข้อความเดียวที่เชื่อถือได้และเรียงตามลำดับ ซึ่งเหมาะสำหรับความต้องการในการสื่อสารบางประเภท หากต้องการลักษณะดังกล่าว API สตรีมของ WebTransport ก็สามารถให้ได้เช่นกัน ในทางตรงกันข้าม API ของ Datagram ของ WebTransport จะให้การนำส่งที่มีเวลาในการตอบสนองต่ำโดยไม่มีการรับประกันความน่าเชื่อถือหรือการจัดลำดับ จึงไม่ใช่การแทนที่ WebSocket โดยตรง
การใช้ WebTransport ผ่าน Datagram API หรือผ่านอินสแตนซ์ Streams API ที่ทำงานพร้อมกันหลายรายการหมายความว่าคุณไม่ต้องกังวลเกี่ยวกับการบล็อกส่วนหัวของบรรทัด ซึ่งอาจเป็นปัญหาที่เกิดขึ้นกับ WebSocket นอกจากนี้ การสร้างการเชื่อมต่อใหม่ยังช่วยเพิ่มประสิทธิภาพได้ด้วย เนื่องจากแฮนด์เชค QUIC ที่อยู่เบื้องหลังนั้นเร็วกว่าการเริ่มต้น TCP ผ่าน TLS
WebTransport เป็นส่วนหนึ่งของข้อกำหนดฉบับร่างใหม่ และด้วยเหตุนี้ ระบบนิเวศ WebSocket รอบๆ ไลบรารีไคลเอ็นต์และเซิร์ฟเวอร์จึงมีความแข็งแกร่งมากกว่าในปัจจุบัน หากคุณต้องการสิ่งที่ใช้งานได้ "ทันที" กับการตั้งค่าเซิร์ฟเวอร์ทั่วไปและรองรับไคลเอ็นต์เว็บอย่างกว้างขวาง WebSocket เป็นตัวเลือกที่ดีกว่าในปัจจุบัน
WebTransport เหมือนกับ UDP Socket API ไหม
ไม่ WebTransport ไม่ใช่ UDP Socket API แม้ว่า WebTransport จะใช้ HTTP/3 ซึ่งใช้ UDP "เบื้องหลัง" แต่ WebTransport มีข้อกำหนดเกี่ยวกับการเข้ารหัสและการควบคุมความแออัดที่ทำให้ WebTransport เป็นมากกว่า API ซ็อกเก็ต UDP พื้นฐาน
WebTransport เป็นทางเลือกแทนช่องข้อมูล WebRTC หรือไม่
ได้ สำหรับการเชื่อมต่อไคลเอ็นต์-เซิร์ฟเวอร์ WebTransport มีพร็อพเพอร์ตี้หลายอย่างเหมือนกับช่องข้อมูล WebRTC แม้ว่าโปรโตคอลพื้นฐานจะแตกต่างกัน
โดยทั่วไป การเรียกใช้เซิร์ฟเวอร์ที่รองรับ HTTP/3 จะต้องมีการตั้งค่าและการกำหนดค่าน้อยกว่าการดูแลเซิร์ฟเวอร์ WebRTC ซึ่งเกี่ยวข้องกับการทำความเข้าใจโปรโตคอลหลายรายการ (ICE, DTLS และ SCTP) เพื่อให้ได้การรับส่งที่ใช้งานได้ WebRTC มีองค์ประกอบที่เคลื่อนไหวได้อีกมากมายซึ่งอาจทำให้การเจรจาระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ไม่สำเร็จ
WebTransport API ได้รับการออกแบบโดยคำนึงถึง Use Case ของนักพัฒนาเว็บ และควรให้ความรู้สึกเหมือนการเขียนโค้ดแพลตฟอร์มเว็บสมัยใหม่มากกว่าการใช้อินเทอร์เฟซช่องข้อมูลของ WebRTC WebTransport รองรับภายใน Web Worker ซึ่งต่างจาก WebRTC ทำให้คุณสามารถสื่อสารระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ได้โดยไม่ขึ้นอยู่กับหน้า HTML ที่ระบุ เนื่องจาก WebTransport แสดงอินเทอร์เฟซที่สอดคล้องกับ Streams จึงรองรับการเพิ่มประสิทธิภาพเกี่ยวกับแรงดันย้อนกลับ
อย่างไรก็ตาม หากคุณมีการตั้งค่าไคลเอ็นต์/เซิร์ฟเวอร์ WebRTC ที่ใช้งานได้อยู่แล้วและพึงพอใจกับการตั้งค่าดังกล่าว การเปลี่ยนไปใช้ WebTransport อาจไม่ได้มีข้อดีมากนัก
ลองเลย
วิธีที่ดีที่สุดในการทดลองใช้ WebTransport คือการเริ่มต้นเซิร์ฟเวอร์ HTTP/3 ที่เข้ากันได้ จากนั้นคุณจะใช้หน้านี้กับไคลเอ็นต์ JavaScript พื้นฐานเพื่อลองใช้การสื่อสารระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ได้
นอกจากนี้ ยังมีเซิร์ฟเวอร์ Echo ที่ชุมชนดูแลอยู่ที่ webtransport.day
การใช้ API
WebTransport ได้รับการออกแบบบนพื้นฐานของแพลตฟอร์มเว็บที่ทันสมัย เช่น Streams API โดยจะอาศัยสัญญาเป็นอย่างมาก และทำงานได้ดีกับ async
และ await
การใช้งาน WebTransport ใน Chromium ปัจจุบันรองรับการรับส่งข้อมูล 3 ประเภท ได้แก่ Datagram รวมถึงสตรีมแบบทิศทางเดียวและแบบสองทิศทาง
การเชื่อมต่อกับเซิร์ฟเวอร์
คุณเชื่อมต่อกับเซิร์ฟเวอร์ HTTP/3 ได้โดยการสร้างWebTransport
อินสแตนซ์ รูปแบบของ URL ควรเป็น https
คุณต้องระบุหมายเลขพอร์ตอย่างชัดเจน
คุณควรใช้สัญญา ready
เพื่อรอให้ระบบสร้างการเชื่อมต่อ ระบบจะไม่ดำเนินการตามสัญญานี้จนกว่าการตั้งค่าจะเสร็จสมบูรณ์ และจะปฏิเสธหากการเชื่อมต่อล้มเหลวในขั้นตอน QUIC/TLS
closed
สัญญาจะดำเนินการให้เสร็จสมบูรณ์เมื่อการเชื่อมต่อปิดตามปกติ และจะปฏิเสธหากการปิดนั้นไม่คาดคิด
หากเซิร์ฟเวอร์ปฏิเสธการเชื่อมต่อเนื่องจากข้อผิดพลาดการระบุไคลเอ็นต์ (เช่น เส้นทางของ URL ไม่ถูกต้อง) จะทำให้ closed
ปฏิเสธ ในขณะที่ ready
ยังคงไม่ได้รับการแก้ไข
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.t>hen(() = {
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 APIs
เมื่อมีอินสแตนซ์ WebTransport ที่เชื่อมต่อกับเซิร์ฟเวอร์แล้ว คุณจะใช้เพื่อส่งและรับข้อมูลแบบแยกส่วนที่เรียกว่าดาต้าแกรมได้
writeable
Getter จะแสดงผล WritableStream
ซึ่งเว็บไคลเอ็นต์ใช้เพื่อส่งข้อมูลไปยังเซิร์ฟเวอร์ได้ readable
Getter จะแสดง ReadableStream
ซึ่งช่วยให้คุณรับฟังข้อมูลจากเซิร์ฟเวอร์ได้ ทั้ง 2 สตรีมนี้ไม่น่าเชื่อถือโดยธรรมชาติ ดังนั้นจึงเป็นไปได้ที่เซิร์ฟเวอร์จะไม่ได้รับข้อมูลที่คุณเขียน และในทางกลับกัน
สตรีมทั้ง 2 ประเภทใช้อินสแตนซ์ Uint8Array
สำหรับการโอนข้อมูล
// 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
เมื่อเชื่อมต่อกับเซิร์ฟเวอร์แล้ว คุณยังใช้ WebTransport เพื่อส่งและรับข้อมูลผ่าน Streams API ได้ด้วย
โดยแต่ละก้อนของสตรีมทั้งหมดคือ Uint8Array
สตรีมเหล่านี้เชื่อถือได้ ซึ่งต่างจาก Datagram API แต่แต่ละสตรีมเป็นอิสระต่อกัน จึงไม่รับประกันลำดับข้อมูลในสตรีม
WebTransportSendStream
ไคลเอ็นต์ของเว็บจะสร้าง WebTransportSendStream
โดยใช้วิธี createUnidirectionalStream()
ของอินสแตนซ์ WebTransport
ซึ่งจะแสดงผล Promise สำหรับ WebTransportSendStream
ใช้เมธอด close()
ของ WritableStreamDefaultWriter
เพื่อปิดสตรีม HTTP/3 ที่เชื่อมโยง เบราว์เซอร์จะพยายามส่งข้อมูลที่รอดำเนินการทั้งหมดก่อนที่จะปิดสตรีมที่เชื่อมโยงจริงๆ
// 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: ${erro
r}`);
}
ในทำนองเดียวกัน ให้ใช้วิธี abort()
ของ WritableStreamDefaultWriter
เพื่อส่ง RESET_STREAM
ไปยังเซิร์ฟเวอร์ เมื่อใช้ abort()
เบราว์เซอร์อาจทิ้งข้อมูลที่รอดำเนินการซึ่งยังไม่ได้ส่ง
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
การขอ WebTransportReceiveStream
เป็นกระบวนการ 2 ขั้นตอนสำหรับเว็บไคลเอ็นต์ ก่อนอื่น ฟังก์ชันจะเรียกแอตทริบิวต์ incomingUnidirectionalStreams
ของอินสแตนซ์ WebTransport
ซึ่งจะแสดงผล ReadableStream
ReadableStream
แต่ละก้อนนั้นเป็น WebTransportReceiveStream
ที่ใช้เพื่ออ่านอินสแตนซ์ Uint8Array
ที่เซิร์ฟเวอร์ส่งมาได้
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);
}
คุณตรวจหาการปิดสตรีมได้โดยใช้สัญญา closed
ของ ReadableStreamDefaultReader
เมื่อสตรีม HTTP/3 พื้นฐานปิดด้วยบิต FIN ระบบจะทำตามclosed
สัญญาหลังจากอ่านข้อมูลทั้งหมดแล้ว เมื่อสตรีม HTTP/3 ปิดอย่างกะทันหัน (เช่น โดย RESET_STREAM
) สัญญา closed
จะปฏิเสธ
// Assume an active receiveStream
const reader = receiveStream.readable.getReader();
reader.closed.then(() => {
console.log('The receiveStream closed gracefully.');
}).ca>tch(() = {
console.error('The receiveStream closed abrup
tly.');
});
WebTransportBidirectionalStream
WebTransportBidirectionalStream
อาจสร้างโดยเซิร์ฟเวอร์หรือไคลเอ็นต์
ไคลเอ็นต์ของเว็บสร้างได้โดยใช้วิธี createBidirectionalStream()
ของอินสแตนซ์ WebTransport
ซึ่งจะแสดงผล Promise สำหรับ WebTransportBidirectionalStream
const stream = await transport.createBidirectionalStream();
// stream is a WebTransportBidirectionalStream
// stream.readable is a ReadableStream
// stream.writable is a WritableStream
คุณสามารถฟัง WebTransportBidirectionalStream
ที่เซิร์ฟเวอร์สร้างขึ้นด้วยแอตทริบิวต์ incomingBidirectionalStreams
ของอินสแตนซ์ WebTransport
ซึ่งจะแสดงผล ReadableStream
ReadableStream
แต่ละก้อนจะเป็น 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
เป็นเพียงการรวมกันของ WebTransportSendStream
และ WebTransportReceiveStream
ตัวอย่างจาก 2 ส่วนก่อนหน้าจะอธิบายวิธีใช้แต่ละรายการ
ตัวอย่างเพิ่มเติม
ข้อกําหนดฉบับร่างของ WebTransport มีตัวอย่างเพิ่มเติมแบบอินไลน์อีกหลายรายการ พร้อมด้วยเอกสารประกอบทั้งหมดสําหรับเมธอดและพร็อพเพอร์ตี้ทั้งหมด
WebTransport ในเครื่องมือสำหรับนักพัฒนาเว็บของ Chrome
ขออภัย ขณะนี้ DevTools ของ Chrome ยังไม่รองรับ WebTransport คุณสามารถ "ติดดาว" ปัญหานี้ใน Chrome เพื่อรับการแจ้งเตือนเกี่ยวกับการอัปเดตอินเทอร์เฟซ DevTools
Polyfill
มี Polyfill (หรือ Ponyfill ที่มีฟังก์ชันการทำงานเป็นโมดูลแบบสแตนด์อโลนที่คุณใช้ได้) ชื่อ
webtransport-ponyfill-websocket
ซึ่งใช้ฟีเจอร์บางอย่างของ WebTransport อ่านข้อจำกัดในREADME
ของโปรเจ็กต์อย่างละเอียดเพื่อพิจารณาว่าโซลูชันนี้ใช้ได้กับ Use Case ของคุณหรือไม่
ข้อควรพิจารณาด้านความเป็นส่วนตัวและความปลอดภัย
ดูคำแนะนำที่เชื่อถือได้ในส่วนที่เกี่ยวข้องของข้อกำหนดฉบับร่าง
ความคิดเห็น
ทีม Chrome อยากทราบความคิดเห็นและประสบการณ์การใช้งาน API นี้ของคุณ
ความคิดเห็นเกี่ยวกับการออกแบบ API
มีอะไรเกี่ยวกับ API ที่ไม่สะดวกหรือทำงานไม่เป็นไปตามที่คาดไว้ไหม หรือมีสิ่งใดที่ขาดหายไปซึ่งคุณต้องใช้ในการนำไอเดียไปใช้ไหม
แจ้งปัญหาในที่เก็บ GitHub ของ Web Transport หรือแสดงความคิดเห็นเกี่ยวกับปัญหาที่มีอยู่
หากพบปัญหาในการติดตั้งใช้งาน
หากพบข้อบกพร่องในการใช้งาน Chrome
ยื่นข้อบกพร่องที่ https://new.crbug.com โดยระบุรายละเอียดให้มากที่สุดเท่าที่จะทำได้ พร้อมด้วยวิธีการง่ายๆ ในการจำลองข้อบกพร่อง
หากมีแผนจะใช้ API
การสนับสนุนแบบสาธารณะของคุณช่วยให้ Chrome จัดลําดับความสําคัญของฟีเจอร์ต่างๆ และแสดงให้ผู้ให้บริการเบราว์เซอร์รายอื่นๆ เห็นว่าการสนับสนุนฟีเจอร์เหล่านี้มีความสําคัญเพียงใด
- ส่งทวีตถึง @ChromiumDev โดยใช้แฮชแท็ก
#WebTransport
และรายละเอียดเกี่ยวกับสถานที่และวิธีที่คุณใช้
การสนทนาทั่วไป
คุณใช้ web-transport-dev Google Group สำหรับคำถามหรือปัญหาทั่วไปที่ไม่ได้อยู่ในหมวดหมู่อื่นๆ ได้
คำขอบคุณ
บทความนี้มีข้อมูลจากคำอธิบายเกี่ยวกับ WebTransport, ข้อกำหนดฉบับร่าง และเอกสารการออกแบบที่เกี่ยวข้อง ขอขอบคุณผู้เขียนที่เกี่ยวข้องที่วางรากฐานดังกล่าว
รูปภาพหลักในโพสต์นี้ถ่ายโดย Robin Pierre ใน Unsplash