WebTransport เป็น API ที่ให้บริการการรับส่งข้อความแบบ 2 ทิศทางที่มีเวลาในการตอบสนองต่ำระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ ดูข้อมูลเพิ่มเติมเกี่ยวกับกรณีการใช้งานและวิธีแสดงความคิดเห็นเกี่ยวกับอนาคตของการใช้งาน
ข้อมูลเบื้องต้น
WebTransport คืออะไร
WebTransport คือ Web API ที่ใช้โปรโตคอล HTTP/3 เป็นการขนส่งแบบ 2 ทิศทาง ซึ่งมีไว้สำหรับการสื่อสารแบบ 2 ทางระหว่างเว็บไคลเอ็นต์กับเซิร์ฟเวอร์ HTTP/3 โดยรองรับทั้งการส่งข้อมูลแบบไม่เสถียรผ่าน Datagram API และแบบเสถียรผ่าน Streams API
Datagram เหมาะสําหรับการส่งและรับข้อมูลที่ไม่จำเป็นต้องมีการรับประกันการนำส่งที่มีประสิทธิภาพ แพ็กเก็ตข้อมูลแต่ละรายการมีขีดจำกัดขนาดตาม Maximum Transmission Unit (MTU) ของการเชื่อมต่อพื้นฐาน และอาจส่งสําเร็จหรือไม่สําเร็จก็ได้ และหากมีการโอน แพ็กเก็ตอาจมาถึงในลําดับที่ไม่แน่นอน ลักษณะเหล่านี้ทำให้ Datagram API เหมาะสําหรับการส่งข้อมูลแบบพยายามอย่างเต็มที่และเวลาในการตอบสนองต่ำ คุณอาจคิดว่าดาตาแกรมเป็นข้อความ 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 อาจเป็นโปรโตคอลการสื่อสารที่ใช้ได้
การสื่อสารผ่าน WebSockets เป็นแบบสตรีมข้อความเดียวที่เชื่อถือได้และจัดเรียงตามลำดับ ซึ่งก็เพียงพอสำหรับการสื่อสารบางประเภท หากต้องการลักษณะเหล่านั้น สตรีม API ของ WebTransport ก็สามารถให้ลักษณะเหล่านั้นได้เช่นกัน ในทางกลับกัน Datagram API ของ WebTransport ให้การนําส่งที่มีเวลาในการตอบสนองต่ำ โดยไม่รับประกันความน่าเชื่อถือหรือลําดับ ดังนั้นจึงไม่ใช่การแทนที่ WebSocket โดยตรง
การใช้ WebTransport ผ่าน Datagram API หรือผ่านอินสแตนซ์ Streams API หลายรายการพร้อมกันหมายความว่าคุณไม่จําเป็นต้องกังวลเกี่ยวกับการบล็อกส่วนหัวของคิว ซึ่งอาจเป็นปัญหากับ WebSockets นอกจากนี้ ยังมีประโยชน์ด้านประสิทธิภาพเมื่อสร้างการเชื่อมต่อใหม่ เนื่องจากแฮนด์เชค QUIC ที่อยู่เบื้องหลังจะเร็วกว่าการเริ่มต้น TCP ผ่าน TLS
WebTransport เป็นส่วนหนึ่งของข้อกำหนดฉบับร่างใหม่ ดังนั้นระบบนิเวศ WebSocket รอบๆ ไลบรารีไคลเอ็นต์และเซิร์ฟเวอร์จึงมีประสิทธิภาพมากขึ้นในปัจจุบัน หากต้องการเครื่องมือที่ใช้งานได้ทันทีกับการตั้งค่าเซิร์ฟเวอร์ทั่วไปและรองรับเว็บไคลเอ็นต์ในวงกว้าง WebSockets เป็นตัวเลือกที่ดีกว่าในปัจจุบัน
WebTransport เหมือนกับ UDP Socket API ไหม
ไม่ใช่ WebTransport ไม่ใช่ UDP Socket API แม้ว่า WebTransport จะใช้ HTTP/3 ซึ่งในทางกลับกันก็ใช้ UDP "ใต้ฝากระโปรง" แต่ WebTransport มีข้อกำหนดเกี่ยวกับการเข้ารหัสและการควบคุมความแออัดที่ทำให้เป็นมากกว่า UDP Socket API พื้นฐาน
WebTransport เป็นทางเลือกของช่องทางข้อมูล WebRTC หรือไม่
มี สำหรับการเชื่อมต่อไคลเอ็นต์กับเซิร์ฟเวอร์ WebTransport มีพร็อพเพอร์ตี้หลายรายการเหมือนกับแชแนลข้อมูล WebRTC แม้ว่าโปรโตคอลพื้นฐานจะแตกต่างกันก็ตาม
โดยทั่วไป การใช้งานเซิร์ฟเวอร์ที่เข้ากันได้กับ HTTP/3 จะต้องตั้งค่าและกำหนดค่าน้อยกว่าการดูแลรักษาเซิร์ฟเวอร์ WebRTC ซึ่งเกี่ยวข้องกับการทำความเข้าใจโปรโตคอลหลายรายการ (ICE, DTLS และ SCTP) เพื่อให้การรับส่งข้อมูลทำงานได้ WebRTC ประกอบด้วยชิ้นส่วนที่เคลื่อนไหวอีกมากมายซึ่งอาจทําให้การเจรจาระหว่างไคลเอ็นต์/เซิร์ฟเวอร์ไม่สําเร็จ
WebTransport API ได้รับการออกแบบโดยคำนึงถึง Use Case ของนักพัฒนาเว็บ และควรให้ความรู้สึกเหมือนเขียนโค้ดแพลตฟอร์มเว็บสมัยใหม่มากกว่าการใช้อินเทอร์เฟซช่องทางข้อมูลของ WebRTC WebTransport รองรับใน Web Worker ซึ่งช่วยให้คุณสื่อสารระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ได้โดยไม่ขึ้นอยู่กับหน้า HTML ใดหน้าหนึ่ง ต่างจาก WebRTC เนื่องจาก WebTransport แสดงอินเทอร์เฟซที่เป็นไปตามข้อกำหนดของ Streams จึงรองรับการเพิ่มประสิทธิภาพเกี่ยวกับแรงดันย้อนกลับ
อย่างไรก็ตาม หากคุณมีการตั้งค่าไคลเอ็นต์/เซิร์ฟเวอร์ WebRTC ที่ใช้งานได้และพอใจแล้ว การเปลี่ยนไปใช้ WebTransport อาจไม่มีข้อดีมากมาย
ลองเลย
วิธีที่ดีที่สุดในการทดลองใช้ WebTransport คือเปิดเซิร์ฟเวอร์ HTTP/3 ที่เข้ากันได้ จากนั้นคุณสามารถใช้หน้านี้กับไคลเอ็นต์ JavaScript พื้นฐานเพื่อลองใช้การสื่อสารไคลเอ็นต์/เซิร์ฟเวอร์
นอกจากนี้ เซิร์ฟเวอร์ Echo ที่ชุมชนดูแลรักษามีให้บริการที่ webtransport.day
การใช้ API
WebTransport ได้รับการออกแบบมาบนแพลตฟอร์มเว็บสมัยใหม่แบบพื้นฐาน เช่น Streams API โดยอาศัยสัญญาเป็นส่วนใหญ่ และทำงานร่วมกับ async
และ await
ได้เป็นอย่างดี
การใช้งาน WebTransport ปัจจุบันใน Chromium รองรับการรับส่งข้อมูล 3 ประเภท ได้แก่ ดาตาแกรม รวมถึงสตรีมแบบทิศทางเดียวและแบบ 2 ทิศทาง
การเชื่อมต่อกับเซิร์ฟเวอร์
คุณเชื่อมต่อกับเซิร์ฟเวอร์ 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.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
เมื่ออินสแตนซ์ WebTransport เชื่อมต่อกับเซิร์ฟเวอร์แล้ว คุณจะใช้อินสแตนซ์ดังกล่าวเพื่อส่งและรับข้อมูลแบบแยกส่วนได้ ซึ่งเรียกว่า ดาตาแกรม
Getter ของ writeable
จะแสดงผล WritableStream
ซึ่งเว็บไคลเอ็นต์สามารถใช้เพื่อส่งข้อมูลไปยังเซิร์ฟเวอร์ Getter ของ readable
จะแสดงผล 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
ซึ่งจะแสดงผลพรอมต์สําหรับ 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: ${error}`);
}
ในทํานองเดียวกัน ให้ใช้เมธอด 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.');
}).catch(() => {
console.error('The receiveStream closed abruptly.');
});
WebTransportBidirectionalStream
WebTransportBidirectionalStream
อาจสร้างโดยเซิร์ฟเวอร์หรือไคลเอ็นต์ก็ได้
ไคลเอ็นต์เว็บสามารถสร้างโดยใช้เมธอด createBidirectionalStream()
ของอินสแตนซ์ WebTransport
ซึ่งจะแสดงผลพรอมต์สําหรับ 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
ขออภัย ขณะนี้ เครื่องมือสำหรับนักพัฒนาเว็บของ Chrome ยังไม่รองรับ WebTransport คุณสามารถ "ติดดาว" ปัญหา Chrome นี้เพื่อรับการแจ้งเตือนเกี่ยวกับการอัปเดตในอินเทอร์เฟซของเครื่องมือสำหรับนักพัฒนาเว็บ
โพลีฟิลล์
เรามีโพลีฟิลล์ (หรือโพนี่ฟิลล์ที่ให้บริการฟังก์ชันการทำงานเป็นโมดูลสแตนด์อโลนที่คุณสามารถใช้ได้) ที่ชื่อ webtransport-ponyfill-websocket
ซึ่งใช้ฟีเจอร์บางอย่างของ WebTransport อ่านข้อจำกัดในREADME
ของโปรเจ็กต์อย่างละเอียดเพื่อพิจารณาว่าโซลูชันนี้ใช้ได้กับ Use Case ของคุณหรือไม่
ข้อควรพิจารณาด้านความเป็นส่วนตัวและความปลอดภัย
ดูคำแนะนำที่เชื่อถือได้ในส่วนที่เกี่ยวข้องของข้อกำหนดฉบับร่าง
ความคิดเห็น
ทีม Chrome อยากทราบความคิดเห็นและประสบการณ์ของคุณในการใช้ API นี้
ความคิดเห็นเกี่ยวกับการออกแบบ API
API มีข้อใดที่ทำให้คุณไม่สะดวกหรือทำงานไม่เป็นไปตามที่คาดไว้ไหม หรือมีชิ้นส่วนที่ขาดหายไปซึ่งคุณต้องนำมาใช้กับแนวคิดของคุณ
แจ้งปัญหาใน Web Transport GitHub repo หรือแสดงความคิดเห็นในปัญหาที่มีอยู่
พบปัญหาในการติดตั้งใช้งานใช่ไหม
หากพบข้อบกพร่องในการใช้งาน Chrome
รายงานข้อบกพร่องที่ https://new.crbug.com โดยระบุรายละเอียดให้มากที่สุดเท่าที่จะทำได้ พร้อมวิธีการง่ายๆ ในการจำลองข้อบกพร่อง
หากมีแผนจะใช้ API
การสนับสนุนแบบสาธารณะของคุณช่วยให้ Chrome จัดลําดับความสําคัญของฟีเจอร์ต่างๆ และแสดงให้เห็นว่าการสนับสนุนฟีเจอร์เหล่านี้สำคัญเพียงใดต่อผู้ให้บริการเบราว์เซอร์รายอื่นๆ
- ส่งทวีตถึง @ChromiumDev โดยใช้แฮชแท็ก
#WebTransport
พร้อมรายละเอียดเกี่ยวกับตำแหน่งและวิธีใช้
การสนทนาทั่วไป
คุณสามารถใช้ web-transport-dev Google Group สำหรับคำถามหรือปัญหาทั่วไปที่ไม่ตรงกับหมวดหมู่อื่นๆ
ขอขอบคุณ
บทความนี้รวมข้อมูลจากคำอธิบาย WebTransport, ข้อกำหนดฉบับร่าง และเอกสารการออกแบบที่เกี่ยวข้อง ขอขอบคุณผู้เขียนที่เกี่ยวข้องที่ให้ข้อมูลพื้นฐานดังกล่าว
รูปภาพหลักในโพสต์นี้โดย Robin Pierre จาก Unsplash