استخدام WebTransport

‫WebTransport هي واجهة برمجة تطبيقات توفّر مراسلة بين العميل والخادم ثنائية الاتجاه ووقت استجابة منخفض. اطّلِع على مزيد من المعلومات حول حالات الاستخدام وكيفية تقديم ملاحظات حول مستقبل التنفيذ.

الخلفية

ما هو WebTransport؟

WebTransport هي واجهة برمجة تطبيقات ويب تستخدِم بروتوكول HTTP/3 لنقل البيانات في الاتجاهين. وهو مخصّص للاتصالات المتبادلة بين برنامج ويب وخادم HTTP/3. ويتيح إرسال البيانات بشكل غير موثوق من خلال واجهات برمجة التطبيقات الخاصة بالبيانات، وبشكل موثوق من خلال واجهات برمجة التطبيقات الخاصة بالبث.

الحِزم النصية مثالية لإرسال وتلقّي البيانات التي لا تحتاج إلى ضمانات تسليم قوية. يتم تحديد حجم الحِزم الفردية للبيانات حسب وحدة النقل القصوى (MTU) للاتصال الأساسي، وقد يتم نقلها بنجاح أو لا، وإذا تم نقلها، قد تصل بترتيب عشوائي. تجعل هذه السمات واجهات برمجة تطبيقات البيانات المصغّرة مثالية لنقل البيانات بأقل وقت استجابة وبأفضل جهد. يمكنك اعتبار مخططات البيانات على أنّها رسائل بروتوكول مخطّط بيانات المستخدم (UDP)، ولكنّها مشفّرة ويتم التحكّم في الازدحام.

في المقابل، توفّر واجهات برمجة التطبيقات لأحداث البث نقل بيانات موثوق ومُرتَّب. وهي مناسبة تمامًا للسيناريوهات التي تحتاج فيها إلى إرسال مصدر بيانات واحد أو أكثر من البيانات المرتبطة أو استلامها. يشبه استخدام أحداث WebTransport المتعددة عملية إنشاء اتصالات متعددة عبر بروتوكول TCP، ولكن بما أنّ HTTP/3 يستخدم بروتوكول QUIC الأخف وزنًا، يمكن فتح هذه الأحداث وإغلاقها بدون الكثير من عمليات التحميل.

حالات الاستخدام

في ما يلي قائمة صغيرة بالطرق المحتملة التي قد يستخدم بها المطوّرون WebTransport.

  • إرسال حالة اللعبة على فترات زمنية منتظمة مع الحد الأدنى من وقت الاستجابة إلى خادم من خلال رسائل صغيرة وغير موثوقة وغير مرتبة
  • تلقّي مصادر الوسائط التي يتم دفعها من خادم بأقل وقت استجابة، بغض النظر عن مصادر البيانات الأخرى
  • تلقّي إشعارات يتم دفعها من خادم عندما تكون صفحة ويب مفتوحة

يهمّنا معرفة المزيد عن كيفية تخطيطك لاستخدام WebTransport.

دعم المتصفح

توافق المتصفّح

  • Chrome: 97
  • Edge: ‏ 97
  • Firefox: 114.
  • Safari: غير متوافق

المصدر

كما هو الحال مع جميع الميزات التي لا تتوفّر لها ميزة التوافق مع جميع المتصفحات، يُعدّ الترميز الدفاعي من خلال رصد الميزات من أفضل الممارسات.

الوضع الحالي

الخطوة الحالة
1. إنشاء فيديو توضيحي مكتمل
2. إنشاء مسودة أولية للمواصفة مكتمل
3- جمع الملاحظات وتحسين التصميم مكتملة
4. مرحلة التجربة والتقييم مكتملة
5- إطلاق Chromium 97

علاقة WebTransport بالتكنولوجيات الأخرى

هل WebTransport بديل لبروتوكول WebSocket؟

ربما. هناك حالات استخدام قد يكون فيها WebSockets أو WebTransport بروتوكولَي اتصال صالحَين للاستخدام.

يتم وضع نماذج لاتصالات WebSockets حول بث واحد موثوق به ومُرتَّب للرسائل، وهو أمر مناسب لبعض أنواع احتياجات الاتصال. إذا كنت بحاجة إلى هذه الخصائص، يمكن أن تقدّمها لك واجهات برمجة التطبيقات الخاصة ببث WebTransport أيضًا. في المقابل، توفّر واجهات برمجة التطبيقات لبيانات WebTransport إمكانية التسليم بوقت استجابة منخفض، بدون ضمانات بشأن الموثوقية أو الترتيب، لذا فهي ليست بديلاً مباشرًا لواجهات WebSocket.

باستخدام WebTransport، من خلال واجهات برمجة تطبيقات البيانات الوصفية أو من خلال عدّة نُسخ متزامنة من واجهة برمجة التطبيقات Streams API، لن يكون عليك القلق بشأن حظر المحتوى في بداية السلسلة، والذي قد يشكّل مشكلة في WebSockets. بالإضافة إلى ذلك، هناك مزايا للأداء عند إنشاء اتصالات جديدة، لأنّ تأكيد الاتصال الأساسي في بروتوكول QUIC أسرع من بدء بروتوكول TCP عبر بروتوكول أمان طبقة النقل (TLS).

يُعدّ WebTransport جزءًا من مسودة مواصفات جديدة، وبالتالي، فإنّ منظومة WebSocket المتكاملة حول مكتبات العميل والخادم أصبحت في الوقت الحالي أكثر كفاءة. إذا كنت بحاجة إلى حلّ يعمل "جاهزًا للاستخدام" مع عمليات إعداد الخادم الشائعة، ويوفّر دعمًا واسعًا لعملاء الويب، فإنّ بروتوكول WebSocket هو الخيار الأفضل اليوم.

هل WebTransport هو نفسه UDP Socket API؟

لا، WebTransport ليس UDP Socket API. على الرغم من أنّ WebTransport يستخدم HTTP/3، والذي يستخدم بدوره UDP "بشكل غير مرئي"، فإنّ WebTransport لديه متطلبات تتعلّق بتشفير البيانات والتحكّم في الازدحام، ما يجعله أكثر من مجرد واجهة برمجة تطبيقات أساسية لبروتوكول UDP Socket.

هل WebTransport بديل لقنوات بيانات WebRTC؟

نعم، لعمليات الاتصال بين العميل والخادم. يتشارك WebTransport العديد من السمات نفسها مع قنوات بيانات WebRTC، على الرغم من اختلاف البروتوكولات الأساسية.

بشكل عام، يتطلّب تشغيل خادم متوافق مع HTTP/3 إعدادًا وضبطًا أقلّ من صيانة خادم WebRTC، ما يتطلّب فهم بروتوكولات متعدّدة (ICE وDTLS وSCTP) للحصول على عملية نقل صالحة. تتضمن WebRTC العديد من العناصر المتغيرة التي قد تؤدي إلى تعذُّر مفاوضات العميل/الخادم.

تم تصميم WebTransport API مع وضع حالات استخدام مطوّري الويب في الاعتبار، ومن المفترض أن تشبه كتابة رمز منصة ويب حديث أكثر من استخدام واجهات قناة البيانات في WebRTC. على عكس WebRTC، يتوفّر WebTransport داخل Web Workers، ما يتيح لك إجراء اتصالات بين العميل والخادم بغض النظر عن صفحة HTML معيّنة. بما أنّ WebTransport يعرِض واجهة متوافقة مع Streams، فهو يتيح تحسينات حول الضغط الخلفي.

ومع ذلك، إذا كان لديك حاليًا إعداد عميل/خادم WebRTC يعمل بشكل جيد وتشعر بالرضا عنه، قد لا يقدّم لك التبديل إلى WebTransport مزايا كثيرة.

جرّبه الآن

إنّ أفضل طريقة لتجربة WebTransport هي تشغيل خادم HTTP/3 متوافق. يمكنك بعد ذلك استخدام هذه الصفحة مع برنامج أساسي لاستخدام JavaScript لتجربة اتصالات العميل/الخادم.

بالإضافة إلى ذلك، يتوفّر خادم صدى تديره جهات خارجية على الرابط webtransport.day.

استخدام واجهة برمجة التطبيقات

تم تصميم WebTransport استنادًا إلى العناصر الأساسية لواجهة برمجة تطبيقات الويب الحديثة، مثل Streams API. ويعتمد بشكل كبير على التعهدات، ويعمل بشكل جيد مع async وawait.

يتيح تطبيق WebTransport الحالي في Chromium ثلاثة أنواع مختلفة من الزيارات: الحِزم، بالإضافة إلى أحداث البث أحادي الاتجاه وثنائي الاتجاه.

الاتصال بخادم

يمكنك الاتصال بخادم HTTP/3 من خلال إنشاء مثيل WebTransport. يجب أن يكون مخطّط عنوان URL هو https. عليك تحديد رقم المنفذ صراحةً.

يجب استخدام ready promise للانتظار إلى أن يتم إنشاء الرابط. لن يتم الوفاء بهذا الوعد إلى أن تكتمل عملية الإعداد، وسيتم رفضه في حال تعذّر الاتصال في مرحلة 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

بعد إنشاء مثيل WebTransport متصل بخادم، يمكنك استخدامه لإرسال وتلقّي أجزاء منفصلة من البيانات، والتي تُعرف باسم datagrams.

يعرض مُستخدِم writeable WritableStream، والذي يمكن لبرنامج ويب استخدامه لإرسال البيانات إلى الخادم. يعرض مُستخدِم 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);
}

واجهات برمجة التطبيقات الخاصة بالبث

بعد الاتصال بالخادم، يمكنك أيضًا استخدام WebTransport لإرسال البيانات واستلامها من خلال واجهات برمجة التطبيقات Streams APIs.

كل جزء من جميع أحداث البث هو Uint8Array. على عكس واجهات برمجة التطبيقات 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 للحصول على إشعارات بشأن التعديلات على واجهة "أدوات مطوّري البرامج في Chrome".

حشو بوليستر

يتوفّر polyfill (أو بالأحرى ponyfill الذي يقدّم وظائف كوحدة مستقلة يمكنك استخدامها) يُسمى webtransport-ponyfill-websocket وينفّذ بعض ميزات WebTransport. اقرأ بعناية القيود الواردة في README المشروع لتحديد ما إذا كان هذا الحلّ مناسبًا لحالة الاستخدام.

اعتبارات الخصوصية والأمان

اطّلِع على القسم المقابل من مسودة المواصفات للحصول على إرشادات موثوقة.

ملاحظات

يريد فريق Chrome معرفة آرائك وتجاربك باستخدام واجهة برمجة التطبيقات هذه.

ملاحظات حول تصميم واجهة برمجة التطبيقات

هل هناك مشكلة في واجهة برمجة التطبيقات أو لا تعمل على النحو المتوقّع؟ أم هل هناك عناصر ناقصة تحتاجها لتنفيذ فكرتك؟

يمكنك الإبلاغ عن مشكلة في مستودع Web Transport على GitHub، أو إضافة أفكارك إلى مشكلة حالية.

هل هناك مشكلة في التنفيذ؟

هل رصدت خطأ في عملية تنفيذ Chrome؟

يمكنك إرسال بلاغ عن خلل على الرابط https://new.crbug.com. يُرجى تضمين أكبر قدر ممكن من التفاصيل، بالإضافة إلى تعليمات بسيطة لإعادة إنتاج المشكلة.

هل تخطّط لاستخدام واجهة برمجة التطبيقات؟

يساعد دعمك العلني فريق Chrome في تحديد الأولويات للميزات، ويُظهر لموفّري المتصفّحات الآخرين مدى أهمية توفير الدعم لها.

  • أرسِل تغريدة إلى ‎@ChromiumDev باستخدام الهاشتاغ #WebTransport وتقدِّم تفاصيل عن مكان استخدامك للميزة وطريقة استخدامك لها.

مناقشة عامة

يمكنك استخدام مجموعة web-transport-dev على Google للأسئلة أو المشاكل العامة التي لا تندرج ضمن إحدى الفئات الأخرى.

الشكر والتقدير

تتضمّن هذه المقالة معلومات من الشرح الموجز لبروتوكول WebTransport ومسودة المواصفات ومستندات التصميم ذات الصلة. نشكر المؤلّفين المعنيّين على تقديم هذه المعلومات الأساسية.

الصورة الرئيسية في هذا المنشور هي من إنشاء Robin Pierre على Unsplash.