שימוש ב-WebTransport

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.

תמיכת דפדפן

תמיכה בדפדפן

  • 97
  • 97
  • 114
  • x

מקור

כמו בכל התכונות שאין להן תמיכה בדפדפן אוניברסלי, מומלץ לכתוב קוד בצורה המוגנת באמצעות זיהוי תכונות.

הסטטוס הנוכחי

שלב סטטוס
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.