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

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

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

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

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

تتّبع RTCDataChannel نهجًا مختلفًا:

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

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

ملاحظة: الإشارات وSTUN وTURN

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

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

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

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

الإمكانات

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

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

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

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

في ما يلي جدول مفيد من مقالة High Performance Browser Networking (الشبكات العالية الأداء للمتصفّحات) التي كتبها إيليا غريغوريك:

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

بعد ذلك، ستتعرّف على كيفية ضبط 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: في حال ضبطها على true، تزيل هذه القيمة عملية الإعداد التلقائي لقناة بيانات على الجهاز الآخر، ما يوفّر لك طريقة خاصة لإنشاء قناة بيانات بالمعرّف نفسه على الجانب الآخر.
  • id: يتيح لك تقديم معرّف خاص بك للقناة لا يمكن استخدامه إلا مع ضبط negotiated على true)

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

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

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

التشفير إلزامي لجميع مكوّنات 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) وحفظها على قرص المستخدم فقط عندما يكون لديك الملف بالكامل.
  • حجم الجزء: هذه هي أصغر "أجزاء" البيانات لتطبيقك. يجب تقسيم البيانات إلى أجزاء لأنّ هناك حدًا أقصى لحجم الإرسال حاليًا (على الرغم من أنّه سيتم حلّ هذه المشكلة في إصدار مستقبلي من قنوات البيانات). الحد الأقصى المقترَح حاليًا لحجم الجزء هو 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 وحزمة تطوير البرامج (SDK) الخاصة بـ PubNub WebRTC، تنفيذ RTCDataChannel، وتتيح واجهة برمجة التطبيقات الآن استخدام العديد من المنصات على مختلف الأنظمة الأساسية.

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

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