WebTransport הוא ממשק API שמציע הודעות שרת-לקוח עם זמן אחזור קצר ודו-כיווני. למידע נוסף על תרחישים לדוגמה ואיך לתת משוב לגבי העתיד של ההטמעה.
רקע
מה זה WebTransport?
WebTransport הוא ממשק API לאינטרנט שמשתמש בפרוטוקול HTTP/3 כהעברה דו-כיוונית. מיועד לתקשורת דו-כיוונית בין לקוח אינטרנט לשרת HTTP/3. הוא תומך בשליחת נתונים באופן לא מהימן דרך ממשקי ה-API של datagram, וגם באופן מהימן דרך ממשקי ה-API של השידורים.
Datagram הוא אידיאלי לשליחה ולקבלה של נתונים שלא מצריכים התחייבויות אספקה חזקות. חבילות נתונים מוגבלות על ידי יחידת ההעברה המקסימלית (MTU) של החיבור הבסיסי, וייתכן שהן ישודרו בהצלחה, ואם הן מועברות, הן עשויות להגיע בסדר שרירותי. המאפיינים האלה הופכים את ממשקי ה-API של תרשימי הנתונים לאידיאליים להעברת נתונים עם זמן אחזור קצר ועם פוטנציאל הרווחי ביותר. אפשר לחשוב על משתני נתונים כהודעות של פרוטוקול User datagram (UDP), אבל מוצפנות ומבוקרות על ידי עומס.
לעומת זאת, ממשקי ה-API של מקורות הנתונים מספקים העברת נתונים אמינה לפי הסדר. הן מותאמות היטב לתרחישים שבהם צריך לשלוח או לקבל שידור אחד או יותר של נתונים מסודרים. השימוש במספר זרמי WebTransport מקבילים ליצירה של מספר חיבורי TCP, אבל מכיוון ש-HTTP/3 משתמש בפרוטוקול המשקל QUIC הקל יותר מתחת למכסה, כך שאפשר לפתוח ולסגור אותם בלי תקורה גדולה יותר.
תרחישים לדוגמה
רשימה קצרה של דרכים אפשריות שבהן מפתחים יכולים להשתמש ב-WebTransport.
- שליחת מצב משחק במרווחי זמן קבועים עם זמן אחזור מינימלי לשרת באמצעות הודעות קטנות ולא אמינות שלא בסדר.
- קבלת שידורים של מדיה בדחיפה משרת עם זמן אחזור מינימלי, בלי קשר למקורות נתונים אחרים.
- קבלת התראות בדחיפה משרת בזמן שדף אינטרנט פתוח.
נשמח לקבל מידע נוסף על האופן שבו בכוונתך להשתמש ב-WebTransport.
תמיכת דפדפן
כמו בכל התכונות שאין להן תמיכה בדפדפן אוניברסלי, מומלץ לכתוב קוד בצורה המוגנת באמצעות זיהוי תכונות.
הסטטוס הנוכחי
שלב | סטטוס |
---|---|
1. יצירת הסבר | הושלם |
2. יצירת טיוטה ראשונית של מפרט | הושלם |
3. אוספים משוב וחוזרים על העיצוב | התשובה מלאה |
4. גרסת מקור לניסיון | התשובה מלאה |
5. הפעלה | Chromium 97 |
הקשר של WebTransport לטכנולוגיות אחרות
האם WebTransport הוא תחליף ל-WebSockets?
אולי. יש תרחישים לדוגמה שבהם WebSockets או WebTransport עשויים להיות פרוטוקולי תקשורת תקינים לשימוש.
התקשורת של WebSockets מבוססת על רצף הודעות אחד, אמין ומסודר, שמתאים לסוגים מסוימים של צורכי תקשורת. אם אתם צריכים את המאפיינים האלה, תוכלו גם להשתמש בממשקי ה-API של ה-streams של WebTransport. לעומת זאת, ממשקי ה-API של תרשימי הנתונים של WebTransport מספקים זמן אחזור קצר וללא התחייבויות לגבי אמינות או הזמנה, ולכן הם לא תחליף ישיר ל-WebSockets.
כשמשתמשים ב-WebTransport, דרך ממשקי ה-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 תוכנן מתוך מחשבה על תרחישים לדוגמה של מפתחי אתרים, והוא צריך להיות דומה יותר לכתיבת קוד מודרני לפלטפורמת האינטרנט מאשר בממשקים של ערוצי נתונים של WebRTC. בניגוד ל-WebRTC, WebTransport נתמך בתוך עובדי אינטרנט, שמאפשר לכם לבצע תקשורת בין שרתים ללקוחות ללא קשר לדף HTML נתון. מכיוון ש-WebTransport חושף ממשק שתואם ל-Streams, הוא תומך באופטימיזציות של לחץ לאחור.
עם זאת, אם היית מרוצה כבר מהגדרת הלקוח/השרת של WebRTC, ייתכן שהמעבר ל-WebTransport לא יספק יתרונות רבים.
אני רוצה לנסות
הדרך הטובה ביותר להתנסות עם WebTransport היא להפעיל שרת HTTP/3 תואם. לאחר מכן תוכלו להשתמש בדף הזה עם לקוח JavaScript בסיסי כדי לנסות את התקשורת עם הלקוח/השרת.
בנוסף, שרת הד בניהול הקהילה זמין בכתובת webtransport.day.
שימוש ב-API
WebTransport תוכנן על גבי עקרונות בסיסיים של פלטפורמות אינטרנט, כמו Streams API. הוא מסתמך מאוד על הבטחות, ועובד היטב עם 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.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;
ממשקי API של Datagram
אחרי שיש מכונת WebTransport שמחוברת לשרת, אפשר להשתמש בה כדי לשלוח ולקבל קטעי נתונים נפרדים, שנקראים datagrams.
הפונקציה writeable
מחזירה WritableStream
, שלקוח אינטרנט יכול להשתמש בה כדי לשלוח נתונים לשרת. הפונקציה getter של readable
מחזירה 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);
}
ממשקי API של סטרימינג
אחרי שמתחברים לשרת, אפשר גם להשתמש ב-WebTransport כדי לשלוח ולקבל נתונים דרך ממשקי ה-API של Streams.
כל מקטע של כל השידורים הוא 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: ${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
היא תהליך דו-שלבי ללקוח אינטרנט. ראשית, הוא קורא למאפיין 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
. הדוגמאות משני הקטעים הקודמים מסבירות איך להשתמש בכל אחד מהם.
דוגמאות נוספות
מפרט הטיוטה של WebTransport כולל כמה דוגמאות נוספות בתוך השורה, וכן תיעוד מלא של כל השיטות והמאפיינים.
WebTransport בכלי הפיתוח של Chrome
לצערנו, כלי הפיתוח של Chrome לא תומכים כרגע ב-WebTransport. אפשר לסמן את הבעיה הזו ב-Chrome כדי לקבל התראות על עדכונים בממשק של כלי הפיתוח.
פוליפיל
אפשר להשתמש ב-Polyfill (או פשוט ponyfill שמספק פונקציונליות כמודול עצמאי שאפשר להשתמש בו) בשם webtransport-ponyfill-websocket
שמטמיע חלק מהתכונות של WebTransport. חשוב לקרוא בעיון את האילוצים ב-README
של הפרויקט כדי להחליט אם הפתרון הזה יכול להתאים לתרחיש לדוגמה שלכם.
שיקולי פרטיות ואבטחה
ניתן לעיין בקטע המקביל במפרט הטיוטה לקבלת הנחיות מוסמכים.
משוב
צוות Chrome ישמח לשמוע מה דעתכם על השימוש ב-API הזה.
משוב על עיצוב ה-API
האם יש משהו ב-API בעייתי או לא פועל כמצופה? או האם חסרים חלקים שנדרשים לכם כדי ליישם את הרעיון?
דווחו על בעיה במאגר GitHub של Web Transport או הוסיפו את דעתכם לבעיה קיימת.
נתקלתם בבעיה בהטמעה?
האם מצאת באג בהטמעה של Chrome?
אפשר לדווח על באג בכתובת https://new.crbug.com. חשוב לכלול כמה שיותר פרטים, יחד עם הוראות פשוטות לשחזור.
מתכנן להשתמש ב-API?
התמיכה הציבורית שלכם עוזרת ל-Chrome לתעדף תכונות, ומראה לספקי דפדפנים אחרים עד כמה חיוני לספק תמיכה בתכונות האלה.
- ניתן לשלוח ציוץ לכתובת @ChromiumDev באמצעות ה-hashtag
#WebTransport
ופרטים על המקום ואופן השימוש בו.
דיון כללי
כדי לענות על שאלות או בעיות כלליות שלא מתאימות לאחת מהקטגוריות האחרות, אפשר להשתמש בקבוצת Google בנושא web-transport-dev.
אישורים
המאמר הזה משלב מידע מ-WebTransport Explainer, מטיוטת מפרט וממסמכי תכנון קשורים. אנחנו מודים לך על יצירת הבסיס למחברים.
התמונה הראשית בפוסט הזה היא של רובין פייר ב-UnFlood.