إرسال البيانات بين المتصفِّحات باستخدام قنوات بيانات WebRTC

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

يمكن الحدّ من هذه المشاكل باستخدام واجهة برمجة التطبيقات RTCDataChannel في WebRTC لنقل البيانات مباشرةً من نظير إلى آخر. تتناول هذه المقالة أساسيات إعداد قنوات البيانات واستخدامها، بالإضافة إلى حالات الاستخدام الشائعة على الويب اليوم.

ما الذي يميّز قناة بيانات أخرى؟

لدينا WebSocket وAJAX وServer Send Events. لماذا نحتاج إلى قناة اتصال أخرى؟ يكون WebSocket ثنائي الاتجاه، ولكن جميع هذه التقنيات مصممة للاتصال من الخادم أو من خلاله.

تعتمد استراتيجية RTCDataChannel نهجًا مختلفًا:

  • وتعمل هذه الخدمة مع واجهة برمجة التطبيقات RTCPeerConnection التي تتيح الاتصال من خلال شبكة الند للند. وقد ينتج عن ذلك تقليل وقت الاستجابة - أي عدم توفُّر خادم وسيط وقليل من "القفزات".
  • يستخدم RTCDataChannel بروتوكول إرسال التحكم في البث (SCTP)، الذي يسمح بإعداد دلالات قابلة للضبط للتسليم بدون الطلب وإعادة الإرسال.

يتوفر RTCDataChannel الآن مع دعم SCTP على أجهزة سطح المكتب وأجهزة Android في Google Chrome وOpera وFirefox.

تنبيه: الإشارة والصغيرة والالتفاف

تتيح خدمة WebRTC الاتصال من نظير إلى نظير، ولكنها لا تزال بحاجة إلى خوادم للإشارة لتبادل البيانات الوصفية للوسائط والشبكة من أجل بدء اتصال من نظير بنظير.

تتعامل WebRTC مع بروتوكول ترجمة عنوان الشبكة (NAT) وجدران الحماية مع:

  • إطار عمل ICE لإنشاء أفضل مسار ممكن لشبكة التواصل بين التطبيقات المشابهة
  • خوادم STUN للتأكد من عنوان IP ومنفذ يمكن الوصول إليهما بشكل علني لكل من التطبيقات المشابهة
  • تدوير الخوادم إذا تعذّر الاتصال المباشر وكان نقل البيانات مطلوبًا.

لمزيد من المعلومات حول آلية عمل WebRTC مع الخوادم الخاصة بالإشارة والاتصال بالشبكات، يُرجى الاطّلاع على WebRTC في الواقع: STUN، وCurrent، والإشارات.

الإمكانات

تتيح واجهة برمجة التطبيقات RTCDataChannel استخدام مجموعة مرنة من أنواع البيانات. تم تصميم واجهة برمجة التطبيقات لمحاكاة WebSocket تمامًا، ويتوافق RTCDataChannel مع السلاسل بالإضافة إلى بعض الأنواع الثنائية في JavaScript، مثل Blob وArrayBuffer وArrayBufferView. يمكن أن تكون هذه الأنواع مفيدة عند التعامل مع نقل الملفات والألعاب المتعدّدة اللاعبين.

يمكن أن تعمل RTCDataChannel في وضع غير موثوق به وغير مرتَّب (المشابه لبروتوكول مخطط بيانات المستخدم أو UDP)، والوضع الموثوق به والمرتب (المشابه لبروتوكول التحكم في الإرسال أو TCP)، والأوضاع الجزئية الموثوق بها:

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

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

في ما يلي جدول مفيد من إعداد الاتصال بالشبكات العالية الأداء من إعداد إيليا غريغوريك:

TCPUDPبروتوكول SCTP
الموثوقيةموثوق بهغير موثوقةقابل للضبط
خدمة توصيلتم الطلببدون ترتيبقابل للضبط
انتقال العدوىالبيانات المستندة إلى البايتموجّه نحو الرسائلموجّه نحو الرسائل
التحكم في التدفقنعملانعم
السيطرة على الاحتقاننعملانعم

بعد ذلك، ستتعرف على كيفية ضبط RTCDataChannel لاستخدام وضع موثوق به وغير مرتَّب أو غير موثوق به.

ضبط قنوات البيانات

هناك عدة عروض توضيحية بسيطة لـ RTCDataChannel على الإنترنت:

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

التعليمة البرمجية اللازمة للبدء في هذا قصيرة:

const peerConnection = new RTCPeerConnection();

// Establish your peer connection using your signaling channel here
const dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

dataChannel.onerror = (error) => {
  console.log("Data Channel Error:", error);
};

dataChannel.onmessage = (event) => {
  console.log("Got Data Channel Message:", event.data);
};

dataChannel.onopen = () => {
  dataChannel.send("Hello World!");
};

dataChannel.onclose = () => {
  console.log("The Data Channel is Closed");
};

يتم إنشاء الكائن dataChannel من اتصال نظير سبق أن تم إنشاؤه. ويمكن إنشاؤها قبل أو بعد حدوث الإشارة. ثم تدخِل تصنيفًا لتمييز هذه القناة عن القنوات الأخرى ومجموعة من إعدادات الضبط الاختيارية:

const dataChannelOptions = {
  ordered: false, // do not guarantee order
  maxPacketLifeTime: 3000, // in milliseconds
};

من الممكن أيضًا إضافة خيار maxRetransmits (عدد المرات التي يمكن تجربتها قبل تعذُّر الإرسال)، ولكن يمكنك فقط تحديد maxRetransmits أو maxPacketLifeTime، وليس كليهما. بالنسبة إلى دلالات UDP، اضبط maxRetransmits على 0 وordered على false. للمزيد من المعلومات، يُرجى الاطّلاع على طلبات التعليقات (RFC) لمجموعة IETF: بروتوكول الإرسال للتحكم في البث وإضافة الموثوقية الجزئية لبروتوكول التحكم في البث.

  • ordered: ما إذا كان يجب أن تضمن قناة البيانات الطلب أم لا
  • maxPacketLifeTime: الحد الأقصى للوقت لمحاولة إعادة إرسال رسالة تعذّر إرسالها
  • maxRetransmits: الحد الأقصى لعدد مرات محاولة إعادة إرسال رسالة تعذّر نقلها
  • protocol: يسمح باستخدام بروتوكول فرعي يوفّر معلومات وصفية حول التطبيق
  • negotiated: في حال ضبط هذه السياسة على "صحيح"، تتم إزالة الإعداد التلقائي لقناة بيانات على شبكة البيانات المشابهة الأخرى، ما يوفّر طريقتك الخاصة لإنشاء قناة بيانات برقم التعريف نفسه على الجانب الآخر.
  • id: تتيح لك هذه الطريقة تقديم معرّف القناة الذي يمكن استخدامه فقط مع ضبط السمة negotiated على true.)

الخيارات الوحيدة التي يحتاج معظم المستخدمين إلى استخدامها هي الخيارات الثلاثة الأولى: ordered وmaxPacketLifeTime وmaxRetransmits. مع بروتوكول SCTP (الذي يتم استخدامه الآن من خلال جميع المتصفحات التي تتوافق مع WebRTC)، يتم الاعتماد عليه وترتيبه على "صحيح" تلقائيًا. من المنطقي استخدام غير موثوق به وغير مرتب إذا كنت تريد التحكم الكامل من طبقة التطبيق، ولكن في معظم الحالات، تكون الموثوقية الجزئية مفيدة.

يُرجى العلم أنّ RTCDataChannel، كما هو الحال في WebSocket، ينشط الأحداث عند إنشاء اتصال أو إغلاقه أو حدوث أخطاء وعند تلقّيه رسالة من تطبيق مشابه.

هل التحدي آمن؟

يكون التشفير إلزاميًا لجميع مكوّنات WebRTC. من خلال RTCDataChannel، يتم تأمين جميع البيانات باستخدام بروتوكول أمان طبقة النقل لمخطّطات البيانات (DTLS). إنّ بروتوكول أمان طبقة النقل لمخطّطات البيانات (DTLS) هو مشتق من طبقة المقابس الآمنة، ما يعني أن بياناتك ستكون آمنة مثل أي اتصال قياسي يستند إلى طبقة المقابس الآمنة. يتم توحيد بروتوكول أمان طبقة النقل لمخطّطات البيانات (DTLS) وتضمينه في جميع المتصفحات التي تتوافق مع WebRTC. لمزيد من المعلومات، يمكنك الاطّلاع على Wireshark wiki.

تغيير طريقة تفكيرك في البيانات

قد تمثل معالجة كميات كبيرة من البيانات مشكلة في JavaScript. وكما أوضح مطوِّرو Sharefest، يتطلّب ذلك التفكير في البيانات بطريقة جديدة. إذا كنت تنقل ملفًا أكبر من حجم الذاكرة المتاحة، يجب التفكير في طرق جديدة لحفظ هذه المعلومات. وهنا يأتي دور تقنيات، مثل FileSystem API، كما ترى فيما يلي.

إنشاء تطبيق لمشاركة الملفات

أصبح من الممكن الآن إنشاء تطبيق ويب يمكنه مشاركة الملفات في المتصفح باستخدام "RTCDataChannel". ويعني إنشاء الإصدار فوق RTCDataChannel أنّ بيانات الملف المنقولة يتم تشفيرها ولا تمس خوادم موفّر التطبيق. هذه الوظيفة، بالإضافة إلى إمكانية الاتصال بعدة عملاء للمشاركة بشكل أسرع، تجعل مشاركة ملف WebRTC مرشحًا قويًا للويب.

هناك عدة خطوات مطلوبة لإجراء عملية نقل ناجحة:

  1. قراءة ملف بلغة JavaScript باستخدام File API
  2. التواصل من خلال التواصل مع العملاء باستخدام "RTCPeerConnection"
  3. أنشئ قناة بيانات بين العملاء باستخدام RTCDataChannel.

هناك عدة نقاط يجب مراعاتها عند محاولة إرسال ملفات عبر RTCDataChannel:

  • حجم الملف: إذا كان حجم الملف صغيرًا بشكل معقول ويمكن تخزينه وتحميله كنسخة Blob واحدة، يمكنك تحميله إلى الذاكرة باستخدام File API، ثم إرسال الملف عبر قناة موثوقة كما هو (ولكن يُرجى العلم أنّ المتصفحات تفرض حدودًا على الحد الأقصى لحجم النقل). كلما زاد حجم الملف، زادت الأمور تعقيدًا. عند الحاجة، يتم تحميل مقاطع الملفات وإرسالها إلى تطبيق مشابه آخر، مصحوبةً ببيانات chunkID الوصفية حتى يتمكّن التطبيق المشابهة من التعرّف عليها. لاحظ أنه في هذه الحالة، تحتاج أيضًا إلى حفظ المقاطع أولاً في التخزين بلا اتصال بالإنترنت (على سبيل المثال، باستخدام FileSystem API) وحفظه على قرص المستخدم فقط عندما يكون لديك الملف بالكامل.
  • حجم القطع: هو أصغر "ذرات" للبيانات في تطبيقك. والتقسيم مطلوب لأنّ هناك حدًّا أقصى لحجم الإرسال في الوقت الحالي (على الرغم من أنّه سيتم إصلاحه في إصدار مستقبلي من قنوات البيانات). الاقتراح الحالي للحد الأقصى لحجم المقطع هو 64 كيلوبايت.

بعد نقل الملف بالكامل إلى الجانب الآخر، يمكن تنزيله باستخدام علامة ارتساء:

function saveFile(blob) {
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = 'File Name';
  link.click();
};

تستخدم تطبيقات مشاركة الملفات هذه على PubShare وGitHub هذه التقنية. وكلاهما برنامج مفتوح المصدر ويقدِّمان أساسًا جيدًا لتطبيق مشاركة الملفات استنادًا إلى RTCDataChannel.

إذًا، ما الذي يمكنك القيام به؟

يفتح RTCDataChannel الأبواب أمام طرق جديدة لتصميم تطبيقات لمشاركة الملفات، وتشغيل الألعاب المتعددة اللاعبين، وتسليم المحتوى.

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

تغيير طريقة إنشاء التطبيقات

يمكنك الآن توفير تطبيقات أكثر تفاعلاً باستخدام اتصالات عالية الأداء بوقت استجابة سريع من خلال RTCDataChannel. تسهّل إطارات العمل، مثل PeerJS وPubNub WebRTC SDK تنفيذ RTCDataChannel، وتصبح واجهة برمجة التطبيقات متاحة الآن على نطاق واسع على جميع الأنظمة الأساسية.

قد يؤدي توفير RTCDataChannel إلى تغيير طريقة تفكيرك في نقل البيانات في المتصفح.

التعرف على المزيد