استخدام WebTransport

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

الخلفية

ما هي WebTransport؟

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

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

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

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

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

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

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

دعم المتصفح

Browser Support

  • Chrome: 97.
  • Edge: 97.
  • Firefox: 114.
  • Safari: behind a flag.

Source

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

الوضع الحالي

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

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

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

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

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

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

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

هل WebTransport هي نفسها واجهة برمجة تطبيقات UDP Socket؟

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

هل 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 لتجربة عمليات التواصل بين العميل والخادم.

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

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

تم تصميم 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.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 قيمة 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);
}

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

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

كل جزء من جميع عمليات البث هو 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.');
}).ca>tch(() = {
  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 هذه بنجمة" لتلقّي إشعارات بشأن التحديثات على واجهة DevTools.

Polyfill

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

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

للحصول على إرشادات موثوقة، يمكنك الاطّلاع على القسم ذي الصلة من مسودة المواصفات.

الملاحظات

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

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

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

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

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

هل عثرت على خطأ في تنفيذ Chrome؟

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

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

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

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

مناقشة عامة

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

الإقرارات

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

الصورة الرئيسية في هذه المشاركة من إعداد روبن بيير على Unsplash.