استخدام WebTransport

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

الخلفية

ما هي WebTransport؟

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

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

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

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

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

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

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

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

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

  • 97
  • 97
  • 114
  • x

المصدر

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

الوضع الحالي

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

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

هل WebTransport بديل لـ WebSockets؟

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

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

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

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

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

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

هل 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.

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

تم تصميم 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;

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

بعد توفُّر مثيل WebTransport متصل بخادم، يمكنك استخدامه لإرسال وحدات بت منفصلة من البيانات واستلامها، والمعروفة باسم مخططات البيانات.

تعرض دالة الحصول على 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.

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

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 معرفة أفكارك وخبراتك باستخدام واجهة برمجة التطبيقات هذه.

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

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

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

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

هل واجهت خطأً في تنفيذ Chrome؟

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

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

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

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

مناقشة عامة

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

شكر وتقدير

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

يتولّى روبن بيير نشر الصورة الرئيسية في هذه المشاركة على منصة Unسبلاش.