WebTransport הוא API שמציע העברת הודעות דו-כיוונית בין לקוח לשרת עם זמן אחזור נמוך. מידע נוסף על תרחישים לדוגמה ועל שליחת משוב לגבי יישום עתידי.
רקע
מה זה WebTransport?
WebTransport הוא Web API שמשתמש בפרוטוקול HTTP/3 כפרוטוקול העברה דו-כיווני. הפרוטוקול מיועד לתקשורת דו-כיוונית בין לקוח אינטרנט לבין שרת HTTP/3. הוא תומך בשליחת נתונים בצורה לא אמינה באמצעות ממשקי ה-API של חבילות הנתונים, ובשליחת נתונים בצורה אמינה באמצעות ממשקי ה-API של הזרמים.
חבילות Datagram הן פתרון אידיאלי לשליחה ולקבלה של נתונים שלא צריך להבטיח את המסירה שלהם. הגודל של כל חבילת נתונים מוגבל על ידי יחידת השידור המקסימלית (MTU) של החיבור הבסיסי, והיא עשויה להיות מועברת בהצלחה או לא, ואם היא מועברת, היא עשויה להגיע בסדר אקראי. המאפיינים האלה הופכים את ממשקי ה-API של חבילות הנתונים לאידיאליים להעברת נתונים עם השהיה נמוכה, תוך השקעת מאמץ מרבי. אפשר לחשוב על דאטגרמים כהודעות של פרוטוקול דאטגרם משתמש (UDP), אבל מוצפנות ועם בקרת עומס.
לעומת זאת, ממשקי ה-API של הזרמים מספקים העברת נתונים אמינה ומסודרת. הם מתאימים במיוחד לתרחישים שבהם צריך לשלוח או לקבל מקור נתונים אחד או יותר של נתונים מסודרים. השימוש בכמה סטרימים של WebTransport דומה ליצירה של כמה חיבורי TCP, אבל מכיוון ש-HTTP/3 משתמש בפרוטוקול QUIC הקל יותר מתחת לפני השטח, אפשר לפתוח ולסגור אותם בלי תקורה גבוהה מדי.
תרחישים לדוגמה
זו רשימה קצרה של דרכים אפשריות שבהן מפתחים יכולים להשתמש ב-WebTransport.
- שליחת מצב המשחק במרווחי זמן קבועים עם השהיה מינימלית לשרת באמצעות הודעות קטנות, לא אמינות ולא מסודרות.
- קבלת סטרימינג של מדיה שנשלח משרת עם השהיה מינימלית, ללא תלות בסטרימינג של נתונים אחרים.
- קבלת התראות שנשלחות משרת בזמן שדף אינטרנט פתוח.
נשמח לשמוע עוד על האופן שבו אתם מתכננים להשתמש ב-WebTransport.
תמיכה בדפדפנים
כמו בכל התכונות שלא נתמכות בכל הדפדפנים, מומלץ להשתמש בזיהוי תכונות כדי לכתוב קוד שיפעל בכל הדפדפנים.
הסטטוס הנוכחי
שלב | סטטוס |
---|---|
1. יצירת הסבר | השלמה |
2. יצירת טיוטה ראשונה של המפרט | השלמה |
3. איסוף משוב ושיפור העיצוב | הושלם |
4. גרסת מקור לניסיון | הושלם |
5. השקה | Chromium 97 |
הקשר בין WebTransport לטכנולוגיות אחרות
האם WebTransport מחליף את WebSockets?
אולי. יש תרחישי שימוש שבהם WebSockets או WebTransport יכולים להיות פרוטוקולי תקשורת תקפים לשימוש.
התקשורת ב-WebSockets מבוססת על זרם יחיד, אמין ומסודר של הודעות, וזה מספיק לסוגים מסוימים של צורכי תקשורת. אם אתם צריכים את המאפיינים האלה, ממשקי ה-API של WebTransport יכולים לספק אותם גם כן. לעומת זאת, ממשקי ה-API של WebTransport מספקים מסירה עם השהיה נמוכה, בלי הבטחות לגבי אמינות או סדר, ולכן הם לא מהווים תחליף ישיר ל-WebSockets.
השימוש ב-WebTransport, באמצעות ממשקי ה-API של datagram או באמצעות כמה מופעים בו-זמניים של Streams API, מאפשר לכם לא לדאוג לגבי חסימה של ראש התור, שיכולה להיות בעיה ב-WebSockets. בנוסף, יש יתרונות בביצועים כשמקימים חיבורים חדשים, כי לחיצת היד הבסיסית של QUIC מהירה יותר מהפעלה של TCP over 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 תוכנן במיוחד לתרחישי שימוש של מפתחי אתרים, והוא אמור להרגיש יותר כמו כתיבת קוד מודרני לפלטפורמת אינטרנט מאשר שימוש בממשקי ערוץ הנתונים של WebRTC. בניגוד ל-WebRTC, WebTransport נתמך בתוך Web Workers, מה שמאפשר לבצע תקשורת בין לקוח לשרת ללא תלות בדף HTML נתון. מכיוון ש-WebTransport חושף ממשק שתואם ל-Streams, הוא תומך באופטימיזציות שקשורות ל-backpressure.
עם זאת, אם כבר יש לכם הגדרת לקוח/שרת של WebRTC שפועלת ואתם מרוצים ממנה, יכול להיות שמעבר ל-WebTransport לא יציע לכם הרבה יתרונות.
רוצה לנסות?
הדרך הטובה ביותר להתנסות ב-WebTransport היא להפעיל שרת HTTP/3 תואם. אחר כך תוכלו להשתמש בדף הזה עם לקוח JavaScript בסיסי כדי לנסות תקשורת בין לקוח לשרת.
בנוסף, שרת הד של קהילה זמין בכתובת webtransport.day.
שימוש ב-API
פרוטוקול WebTransport מבוסס על פרימיטיבים מודרניים של פלטפורמת האינטרנט, כמו Streams API. היא מסתמכת במידה רבה על promises, ופועלת היטב עם async
ועם await
.
ההטמעה הנוכחית של WebTransport ב-Chromium תומכת בשלושה סוגים שונים של תנועה: חבילות נתונים, וגם סטרימינג חד-כיווני ודו-כיווני.
התחברות לשרת
אפשר להתחבר לשרת 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
, ומאפשרת להאזין לנתונים מהשרת. שני הזרמים לא אמינים מטבעם, ולכן יכול להיות שהנתונים שתכתבו לא יתקבלו על ידי השרת, ולהפך.
בשני סוגי הסטרימינג נעשה שימוש במופעים של 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 APIs
אחרי שמתחברים לשרת, אפשר גם להשתמש ב-WebTransport כדי לשלוח ולקבל נתונים באמצעות ממשקי ה-API של הזרמים שלו.
כל מקטע של כל הזרמים הוא Uint8Array
. בניגוד לממשקי ה-API של Datagram, הזרמים האלה אמינים. אבל כל מקור נתונים הוא עצמאי, ולכן אין ערובה לכך שסדר הנתונים יהיה זהה בכל המקורות.
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: ${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
היא תהליך דו-שלבי ללקוח אינטרנט. קודם כול, הפונקציה קוראת למאפיין 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
, שמחזירה הבטחה לטוקן 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
. בדוגמאות משני הקטעים הקודמים מוסבר איך משתמשים בכל אחת מהשיטות.
דוגמאות נוספות
טיוטת המפרט של WebTransport כוללת מספר דוגמאות נוספות בתוך הטקסט, וגם תיעוד מלא של כל השיטות והמאפיינים.
WebTransport בכלי הפיתוח ל-Chrome
לצערנו, כלי הפיתוח של Chrome לא תומכים כרגע ב-WebTransport. אתם יכולים לסמן בכוכב את הבעיה הזו ב-Chrome כדי לקבל עדכונים על הממשק של כלי הפיתוח.
פוליפיל
יש polyfill (או יותר נכון ponyfill שמספק פונקציונליות כמודול עצמאי שאפשר להשתמש בו) שנקרא webtransport-ponyfill-websocket
, שמטמיע חלק מהתכונות של WebTransport. חשוב לקרוא בעיון את האילוצים בREADME
של הפרויקט כדי לקבוע אם הפתרון הזה יכול להתאים לתרחיש השימוש שלכם.
שיקולי פרטיות ואבטחה
הנחיות מוסמכות מופיעות בקטע המתאים במפרט הטיוטה.
משוב
צוות Chrome רוצה לשמוע את דעותיכם ואת חוויות השימוש שלכם ב-API הזה.
משוב על עיצוב ה-API
האם יש משהו ב-API שגורם לבעיות או שלא פועל כמצופה? או שיש חלקים חסרים שצריך להוסיף כדי ליישם את הרעיון?
אפשר לפתוח בעיה במאגר Web Transport ב-GitHub או להוסיף את המחשבות שלכם לבעיה קיימת.
בעיה בהטמעה?
מצאתם באג בהטמעה של Chrome?
מדווחים על באג בכתובת https://new.crbug.com. חשוב לכלול כמה שיותר פרטים, וגם הוראות פשוטות לשחזור הבאג.
מתכננים להשתמש ב-API?
התמיכה הציבורית שלכם עוזרת ל-Chrome לתת עדיפות לתכונות, ומראה לספקי דפדפנים אחרים כמה חשוב לתמוך בהן.
- שולחים ציוץ אל @ChromiumDev באמצעות ההאשטאג
#WebTransport
וכוללים פרטים על המקום והאופן שבהם אתם משתמשים בו.
דיון כללי
אפשר להשתמש בקבוצת Google web-transport-dev לשאלות כלליות או לבעיות שלא מתאימות לאף אחת מהקטגוריות האחרות.
תודות
המאמר הזה כולל מידע מהסבר על WebTransport, מטיוטת המפרט וממסמכי עיצוב קשורים. תודה למחברים הרלוונטיים על יצירת הבסיס הזה.
התמונה הראשית (Hero) בפוסט הזה היא של Robin Pierre ב-Unsplash.