بدء استخدام WebRTC

تُعدّ WebRTC جبهة جديدة في الصراع الطويل لتوفير شبكة ويب مفتوحة وغير معقّدة.

"بريندان إيتش"، مخترع JavaScript

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

هل تريد تجربتها؟ تتوفّر WebRTC على أجهزة الكمبيوتر المكتبي والأجهزة الجوّالة في Google Chrome وSafari وFirefox وOpera. ويمكنك البدء من خلال استخدام تطبيق دردشة الفيديو البسيط على appr.tc:

  1. افتح appr.tc في المتصفح.
  2. انقر على انضمام للانضمام إلى غرفة محادثة والسماح للتطبيق باستخدام كاميرا الويب.
  3. افتح عنوان URL المعروض في نهاية الصفحة في علامة تبويب جديدة أو، الأفضل من ذلك، على جهاز كمبيوتر مختلف.

البدء بسرعة

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

  • للحصول على نظرة عامة حول WebRTC، يمكنك مشاهدة فيديو مؤتمر Google I/O التالي أو الاطّلاع على هذه الشرائح:
  • في حال عدم استخدام واجهة برمجة التطبيقات getUserMedia، يمكنك الاطّلاع على التقاط الصوت والفيديو بتنسيق HTML5 وsimpl.info getUserMedia.
  • للحصول على معلومات عن واجهة برمجة التطبيقات RTCPeerConnection، يمكنك الاطّلاع على المثال التالي و'simpl.info RTCPeerConnection'.
  • للتعرّف على كيفية استخدام WebRTC للخوادم لإرسال الإشارات وجدار الحماية واجتياز NAT، يُرجى الاطّلاع على الرمز وسجلّات وحدة التحكّم من appr.tc.
  • ألا يمكنك الانتظار ورغبتك في تجربة WebRTC الآن؟ يمكنك تجربة بعض أكثر من 20 عرضًا توضيحيًا حول واجهات برمجة تطبيقات JavaScript في WebRTC.
  • هل تواجه مشكلة متعلقة بجهازك وWebRTC؟ انتقِل إلى أداة حل المشاكل في WebRTC.

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

سجلّ WebRTC قصير جدًا

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

في السابق، كانت ميزة "ضبط الصوت في الوقت الفعلي" (RTC) مؤسسية ومعقّدة، ما يتطلّب الحصول على ترخيص باستخدام تقنيات الصوت والفيديو باهظة الثمن أو تطويرها داخليًا. كان دمج تقنية "ضبط الوقت الفعلي" مع المحتوى والبيانات والخدمات الحالية أمرًا صعبًا ويستغرق وقتًا طويلاً، لا سيّما على الويب.

أصبحت دردشة الفيديو عبر Gmail شائعة في عام 2008، وفي عام 2011، قدمت Google Hangouts، التي تستخدم Talk (كما هو الحال في Gmail). اشترت Google شركة GIPS، وهي شركة طوّرت العديد من المكوّنات المطلوبة للضبط في الوقت الفعلي (RTC)، مثل برامج الترميز وتقنيات إلغاء الصدى. أنشأت Google تكنولوجيات مفتوحة المصدر طوّرها "برنامج GIPS" وتعاونت مع هيئات المعايير ذات الصلة في كل من "مجموعة مهندسي شبكة الإنترنت" (IETF) و"اتحاد شبكة الويب العالمية" (W3C) لضمان توافق الآراء في هذا المجال. في أيار (مايو) 2011، صمّمت شركة إريكسون أول عملية تنفيذ لنظام WebRTC.

نفَّذَت WebRTC معايير مفتوحة لاتصال البيانات والصوت والفيديو في الوقت الفعلي بدون مكوّنات إضافية. كانت الحاجة حقيقية:

  • تستخدم العديد من خدمات الويب ضبط الوقت الفعلي (RTC)، ولكنّها كانت تحتاج إلى عمليات تنزيل أو تطبيقات محلية أو مكوّنات إضافية. وشملت هذه الميزات Skype وFacebook وHangouts.
  • إنّ تنزيل المكوّنات الإضافية وتثبيتها وتحديثها هو إجراء معقّد ومعرّض للخطأ ومزعج.
  • يصعب نشر المكوّنات الإضافية وتصحيح أخطائها وتحديد المشاكل وحلّها واختبارها وصيانتها، وقد تتطلب ترخيصًا ودمجًا مع تكنولوجيا معقدة وباهظة التكلفة. يكون من الصعب غالبًا إقناع الأشخاص بتثبيت المكونات الإضافية في المقام الأول!

تنص المبادئ التوجيهية لمشروع WebRTC على أنّ واجهات برمجة التطبيقات الخاصة به يجب أن تكون مفتوحة المصدر ومجانية وموحّدة ومدمجة في متصفحات الويب، وأكثر كفاءة من التكنولوجيات الحالية.

أين نحن الآن؟

يتم استخدام WebRTC في تطبيقات مختلفة، مثل Google Meet. تم أيضًا دمج WebRTC مع التطبيقات الأصلية WebKitGTK+ وQt.

تنفِّذ WebRTC واجهات برمجة التطبيقات الثلاث التالية: - MediaStream (يُعرف أيضًا باسم getUserMedia) - RTCPeerConnection - RTCDataChannel

يتم تحديد واجهات برمجة التطبيقات بالمواصفات التالية:

تتوافق واجهات برمجة التطبيقات الثلاث على الأجهزة الجوّالة وأجهزة الكمبيوتر المكتبي مع المتصفّحات Chrome وSafari وFirefox وEdge وOpera.

getUserMedia: بالنسبة إلى العروض التوضيحية والرموز، يمكنك الاطّلاع على نماذج WebRTC أو تجربة الأمثلة الرائعة من "كريس ويلسون" التي تستخدم getUserMedia كإدخال في الإعدادات الصوتية على الويب.

RTCPeerConnection: للحصول على عرض توضيحي بسيط وتطبيق محادثة فيديو يعمل بكامل وظائفه، يُرجى الاطّلاع على نماذج WebRTC لاتصال الزملاء وappr.tc، على التوالي. يستخدم هذا التطبيق adapter.js، وهو برنامج تحكّم بلغة JavaScript تحتفظ به Google بمساعدة منتدى WebRTC، لإزالة الاختلافات في المتصفّح والتغييرات في المواصفات.

RTCDataChannel: للاطّلاع على ذلك عمليًا، يمكنك الاطّلاع على نماذج WebRTC للاطّلاع على أحد العروض التوضيحية لقنوات البيانات.

يوضح الدرس التطبيقي حول ترميز WebRTC كيفية استخدام واجهات برمجة التطبيقات الثلاث لإنشاء تطبيق بسيط لمحادثات الفيديو ومشاركة الملفات.

أول WebRTC

تحتاج تطبيقات WebRTC إلى تنفيذ عدة إجراءات:

  • الحصول على بث الصوت أو الفيديو أو بيانات أخرى
  • احصل على معلومات الشبكة، مثل عناوين IP والمنافذ، وتبادلها مع برامج WebRTC الأخرى (المعروفة باسم التطبيقات المشابهة) لتفعيل الاتصال، حتى من خلال NAT وبرامج جدار الحماية.
  • تنسيق اتصالات الإشارات للإبلاغ عن الأخطاء وبدء الجلسات أو إغلاقها.
  • تبادل المعلومات حول الوسائط وإمكانيات العميل، مثل درجة الدقة وبرامج الترميز
  • التواصل مع بث الصوت أو الفيديو أو البيانات

للحصول على بيانات البث ونقلها، ينفِّذ WebRTC واجهات برمجة التطبيقات التالية:

  • يحصل MediaStream على إمكانية الوصول إلى مصادر البيانات، مثلاً من كاميرا المستخدم وميكروفونه.
  • تتيح RTCPeerConnection إجراء مكالمات الصوت أو الفيديو باستخدام مرافق للتشفير وإدارة معدل نقل البيانات.
  • تتيح RTCDataChannel اتصال البيانات العامة عن طريق شبكة الند للند.

(تتوفر مناقشة تفصيلية حول الشبكة وجوانب الإشارة في WebRTC لاحقًا).

واجهة برمجة تطبيقات MediaStream (المعروفة أيضًا باسم getUserMedia API)

تعرض واجهة برمجة التطبيقات MediaStream مجموعات بث الوسائط المتزامنة. على سبيل المثال، إذا تم تسجيل بث باستخدام الكاميرا والميكروفون، تزامنًا مع مسارات الصوت والفيديو. (لا تخلِط بين MediaStreamTrack والعنصر <track>، فهو مختلف تمامًا).

قد تكون أسهل طريقة لفهم واجهة برمجة تطبيقات MediaStream هي الاطّلاع على البيانات بشكل تفصيلي:

  1. في المتصفّح، انتقِل إلى نماذج WebRTC getUserMedia.
  2. افتح وحدة التحكّم.
  3. افحص المتغيّر stream، وهو في نطاق عمومي.

ويتضمّن كل MediaStream مدخلاً، وقد يكون MediaStream من إنشاء getUserMedia() ومخرجًا قد يتم تمريره إلى عنصر فيديو أو RTCPeerConnection.

تستخدم الطريقة getUserMedia() معلمة الكائن MediaStreamConstraints وتعرض Promise التي يتم حلها إلى كائن MediaStream.

لكل MediaStream قيمة label، مثل 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'. يتم عرض مصفوفة من MediaStreamTrack من خلال الطريقتَين getAudioTracks() وgetVideoTracks().

في المثال getUserMedia، تعرض stream.getAudioTracks() صفيفًا فارغًا (لأنّه لا يتوفّر صوت)، وعلى افتراض أنّ كاميرا الويب متصلة، يعرض stream.getVideoTracks() مصفوفة واحدة MediaStreamTrack تمثّل البث من كاميرا الويب. ولكل MediaStreamTrack نوع ('video' أو 'audio') وlabel (مثل 'FaceTime HD Camera (Built-in)') وقناة واحدة أو أكثر تتضمّن محتوًى صوتيًا أو فيديو. في هذه الحالة، يكون هناك مسار فيديو واحد فقط بدون صوت، ولكن من السهل تصوّر حالات استخدام أخرى، مثل تطبيق دردشة يبث المحتوى من الكاميرا الأمامية والكاميرا الخلفية والميكروفون وتطبيق يشارك شاشته.

يمكن ربط MediaStream بعنصر فيديو من خلال ضبط السمة srcObject. في السابق، كان يتم إجراء ذلك من خلال ضبط السمة src على عنوان URL لعنصر تم إنشاؤه باستخدام URL.createObjectURL()، ولكن تم إيقافها نهائيًا.

يمكن أيضًا استخدام getUserMedia كعقدة إدخال لواجهة Web Audio API:

// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
  audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
  audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
  console.log('Sorry! Web Audio not supported.');
}

// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;

// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;

navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
  // Create an AudioNode from the stream.
  const mediaStreamSource =
    audioContext.createMediaStreamSource(stream);
  mediaStreamSource.connect(filterNode);
  filterNode.connect(gainNode);
  // Connect the gain node to the destination. For example, play the sound.
  gainNode.connect(audioContext.destination);
});

يمكن أن تتضمن التطبيقات والإضافات المستندة إلى Chromium أيضًا getUserMedia. تؤدي إضافة أذونات audioCapture و/أو videoCapture إلى البيان إلى السماح بطلب الإذن ومنحه مرة واحدة فقط عند التثبيت. بعد ذلك، لا يُطلب من المستخدم الحصول على إذن الوصول إلى الكاميرا أو الميكروفون.

يجب منح الإذن مرة واحدة فقط لـ getUserMedia(). لأول مرة، يتم عرض الزر "سماح" في شريط المعلومات الخاص بالمتصفح. أوقف Chrome إمكانية الوصول إلى بروتوكول HTTP في getUserMedia() بنهاية عام 2015 بسبب تصنيفه كميزة قوية.

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

يمكنك استخدام getUserMedia() مع واجهات برمجة تطبيقات JavaScript والمكتبات الأخرى:

  • Webcam Toy هو تطبيق لتصوير كشك الصور يستخدم WebGL لإضافة تأثيرات غريبة ورائعة إلى الصور التي يمكن مشاركتها أو حفظها محليًا.
  • FaceKat هي لعبة لتتبع الوجوه تم إنشاؤها باستخدام headtrackr.js.
  • تستخدم كاميرا ASCII واجهة برمجة التطبيقات Canvas API لإنشاء صور بتنسيق ASCII.
صورة ASCII تم إنشاؤها بواسطة idevelop.ro/ascii-camera
فن gUM ASCII

القيود

يمكن استخدام القيود لضبط قيم درجة دقة الفيديو لـ getUserMedia(). ويتيح ذلك أيضًا فرض قيود أخرى، مثل نسبة العرض إلى الارتفاع. الوضع المواجه (الكاميرا الأمامية أو الخلفية) عدد اللقطات في الثانية والارتفاع والعرض وطريقة applyConstraints().

على سبيل المثال، يمكنك الاطّلاع على نماذج WebRTC getUserMedia: اختيار درجة الدقة.

ويؤدي ضبط قيمة قيد غير مسموح بها إلى منح DOMException أو OverconstrainedError في حال عدم توفُّر درجة الدقة المطلوبة مثلاً. للاطّلاع على ذلك بشكل عملي، يمكنك الاطّلاع على نماذج WebRTC getUserMedia: اختيار درجة الدقة لعرض توضيحي.

لقطة الشاشة وعلامة التبويب

وتتيح تطبيقات Chrome أيضًا مشاركة فيديو مباشر في علامة تبويب واحدة في المتصفّح أو جهاز كمبيوتر سطح المكتب بأكمله من خلال واجهتَي برمجة التطبيقات chrome.tabCapture وchrome.desktopCapture. (للحصول على عرض توضيحي ومزيد من المعلومات، يُرجى الاطّلاع على مشاركة الشاشة مع WebRTC. هذه المقالة تم إنشاؤها قبل بضع سنوات، ولكنها لا تزال مثيرة للاهتمام).

من الممكن أيضًا استخدام التقاط الشاشة كمصدر MediaStream في Chrome باستخدام قيد chromeMediaSource التجريبي. تجدر الإشارة إلى أنّ تصوير الشاشة يتطلّب بروتوكول HTTPS ويجب استخدامه فقط في عملية التطوير لأنه يتم تفعيله من خلال علامة سطر أوامر كما هو موضّح في هذه المشاركة.

الإشارة: التحكُّم في الجلسات والشبكة ومعلومات الوسائط

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

وبدلاً من ذلك، يمكن لمطوّري تطبيقات WebRTC اختيار بروتوكول المراسلة الذي يفضّلونه، مثل SIP أو XMPP، وأيّ قناة اتصال مناسبة مزدوجة الاتجاه. يستخدم مثال appr.tc XHR وChannel API كآلية الإشارة. يستخدِم الدرس التطبيقي حول الترميز Socket.io الذي يعمل على خادم عقدة.

تُستخدم الإشارة لتبادل ثلاثة أنواع من المعلومات:

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

ويجب أن تكتمل عملية تبادل المعلومات من خلال الإشارة بنجاح قبل بدء البث من نظير لنظير.

على سبيل المثال، تخيل أن نبيلة تريد التواصل مع يوسف. في ما يلي نموذج رمز من مواصفات W3C WebRTC، والذي يعرض عملية الإشارة بشكل عملي. يفترض الرمز وجود آلية إشارات تم إنشاؤها باستخدام طريقة createSignalingChannel(). تجدر الإشارة أيضًا إلى أنّ RTCPeerConnection يسبق الاسم في الوقت الحالي في متصفّح Chrome وOpera.

// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);

// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});

// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
  try {
    await pc.setLocalDescription(await pc.createOffer());
    // Send the offer to the other peer.
    signaling.send({desc: pc.localDescription});
  } catch (err) {
    console.error(err);
  }
};

// Once remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
  // Don't set srcObject again if it is already set.
  if (remoteView.srcObject) return;
  remoteView.srcObject = event.streams[0];
};

// Call start() to initiate.
async function start() {
  try {
    // Get local stream, show it in self-view, and add it to be sent.
    const stream =
      await navigator.mediaDevices.getUserMedia(constraints);
    stream.getTracks().forEach((track) =>
      pc.addTrack(track, stream));
    selfView.srcObject = stream;
  } catch (err) {
    console.error(err);
  }
}

signaling.onmessage = async ({desc, candidate}) => {
  try {
    if (desc) {
      // If you get an offer, you need to reply with an answer.
      if (desc.type === 'offer') {
        await pc.setRemoteDescription(desc);
        const stream =
          await navigator.mediaDevices.getUserMedia(constraints);
        stream.getTracks().forEach((track) =>
          pc.addTrack(track, stream));
        await pc.setLocalDescription(await pc.createAnswer());
        signaling.send({desc: pc.localDescription});
      } else if (desc.type === 'answer') {
        await pc.setRemoteDescription(desc);
      } else {
        console.log('Unsupported SDP type.');
      }
    } else if (candidate) {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

أولاً، يتبادل أليس ويوسف معلومات الشبكة. (يشير التعبير العثور على العناصر المرشحة إلى عملية البحث عن واجهات ومنافذ الشبكات باستخدام إطار عمل ICE.)

  1. تنشئ نبيلة كائن RTCPeerConnection باستخدام معالِج onicecandidate، ويتم تشغيله عندما تصبح الاقتراحات للشبكة متاحة.
  2. ترسل نبيلة بيانات المرشح المتسلسلة إلى خالد من خلال أي قناة إشارة تستخدمها، مثل WebSocket أو آلية أخرى.
  3. عندما يتلقّى خالد رسالة مرشّحة من نبيلة، يتصل بـ "addIceCandidate" لإضافة المرشّح إلى وصف الزميل البعيد.

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

  1. تُشغِّل نبيلة طريقة RTCPeerConnection createOffer(). يتجاوز مدى العرض من هذا الحقل RTCSessionDescription - وصف الجلسة المحلية الخاص بـ "أليس".
  2. أثناء معاودة الاتصال، تضبط نبيلة الوصف المحلي باستخدام setLocalDescription()، ثم ترسل وصف الجلسة هذا إلى خالد من خلال قناة الإشارة. يُرجى العلم أنّ "RTCPeerConnection" لن يبدأ في جمع المرشحين حتى يتم الاتصال بـ setLocalDescription(). تم تنظيم ذلك في مسودة JSEP IETF.
  3. يضبط أمجد الوصف الذي أرسلته ليلى كوصف عن بُعد باستخدام setRemoteDescription().
  4. يستخدم أمجد طريقة RTCPeerConnection createAnswer()، ويضيف الوصف عن بُعد الذي حصل عليه من نبيلة حتى يمكن إنشاء جلسة محلية متوافقة مع محتواها. يتم اجتياز إذن معاودة الاتصال createAnswer() واجتياز RTCSessionDescription. يضبط أمجد ذلك كوصف محلي ويرسله إلى نبيلة.
  5. عندما تحصل نبيلة على وصف جلسة يوسف، يتم ضبط ذلك كوصف عن بُعد باستخدام "setRemoteDescription".
  6. إشعار

كائنات RTCSessionDescription هي وحدات ثنائية كبيرة تتوافق مع بروتوكول وصف الجلسة، وبروتوكول وصف الجلسة (SDP). يبدو كائن SDP المتسلسلة كما يلي:

v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126

// ...

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810

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

يُطلق على بنية العرض/الإجابات الموضّحة سابقًا بروتوكول إنشاء جلسة JavaScript أو JSEP. (تتوفّر صورة متحركة ممتازة تشرح عملية إرسال الإشارات والبث في الفيديو التوضيحي من Ericsson حول تنفيذ WebRTC للمرة الأولى.)

الرسم التخطيطي لبنية JavaScript
بنية JavaScript (JSEP)

بعد اكتمال عملية الإشارة بنجاح، يمكن بث البيانات مباشرةً من نظير إلى نظير، بين المتصل والمُتصل، أو إذا تعذّر ذلك، من خلال خادم إرسال وسيط (سنتناول المزيد من المعلومات عن ذلك لاحقًا). البث من وظيفة "RTCPeerConnection".

RTCPeerConnection

RTCPeerConnection هو مكوِّن WebRTC الذي يعالج الاتصال المستقر والفعّال ببيانات البثّ بين التطبيقات المشابهة.

في ما يلي مخطّط بياني لبنية WebRTC يوضّح دور RTCPeerConnection. كما ستلاحظ، فإن الأجزاء الخضراء معقدة!

مخطّط بنية WebRTC
بنية WebRTC (من webrtc.org)

من منظور JavaScript، أهم ما يجب فهمه من خلال هذا المخطّط البياني هو أنّ RTCPeerConnection يحمي مطوّري البرامج على الويب من التعقيدات الهائلة التي تكمن تحته. تُبذل برامج الترميز والبروتوكولات التي يستخدمها WebRTC جهدًا كبيرًا لجعل الاتصال في الوقت الفعلي ممكنًا، حتى عبر الشبكات غير الموثوقة:

  • إخفاء حزم البيانات
  • إلغاء الصدى
  • توافق معدل نقل البيانات
  • التخزين المؤقت لعدم الاستقرار الديناميكي
  • التحكم الآلي في الصوت
  • تقليل الضوضاء وكتم صوتها
  • تنظيف الصور

يعرض رمز W3C السابق مثالاً مبسطًا على WebRTC من منظور الإشارة. في ما يلي جولة تفصيلية حول اثنين من تطبيقات WebRTC المفيدة. المثال الأول هو مثال بسيط يوضّح السمة RTCPeerConnection والثاني عبارة عن برنامج محادثة فيديو يمكن تشغيله بكامل طاقته.

اتصال RTCPeerConnection بدون خوادم

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

في هذا المثال، يمثل pc1 النظير المحلي (المتصل) ويمثل pc2 نظيره البعيد (الاتصال).

المُتصِل

  1. إنشاء RTCPeerConnection جديد وإضافة ساحة المشاركات من getUserMedia(): ```js // الخوادم هي ملف تهيئة اختياري. (راجع مناقشة turn وSTUN لاحقًا.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) =&gt; { pc1.addTrack(track, localStream); });
  1. يمكنك إنشاء عرض وضبطه كوصف محلي لـ pc1 وكوصف عن بُعد لـ pc2. يمكن إجراء ذلك مباشرةً في الرمز بدون استخدام إشارة لأنّ كلاً من المتصل والمُتصل على الصفحة نفسها: js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );

استدعاء

  1. إنشاء pc2، وعند إضافة البث من "pc1"، يمكنك عرضه في عنصر فيديو: js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }

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

في الواقع، تحتاج WebRTC إلى خوادم رغم بساطتها، لذلك يمكن أن يحدث ما يلي:

  • يكتشف المستخدمون بعضهم البعض ويتبادلون التفاصيل الواقعية، مثل الأسماء.
  • تتبادل تطبيقات برنامج WebRTC (التطبيقات المشابهة) معلومات الشبكة.
  • يتبادل زملاؤك البيانات حول الوسائط، مثل تنسيق الفيديو ودرجة الدقة.
  • تجتاز تطبيقات عميل WebRTC مداخل NAT وجدران الحماية.

بمعنى آخر، تحتاج WebRTC إلى أربعة أنواع من الوظائف من جانب الخادم:

  • اكتشاف المستخدمين والتواصل معهم
  • الإشارة
  • NAT/اجتياز جدار الحماية
  • خوادم الإرسال في حالة فشل الاتصال من نظير إلى نظير

لا تشمل هذه المقالة أيضًا اجتياز NAT وشبكة الند للند ومتطلبات إنشاء تطبيق خادم لاكتشاف المستخدم والإشارة. ويكفي القول بأنّ بروتوكول STUN وامتداده، turn، يستخدِمهما إطار عمل ICE لتمكين RTCPeerConnection من التعامل مع عملية اجتياز NAT والتغييرات الأخرى في الشبكة.

ICE هو إطار عمل لربط النظراء، مثل برنامجَي دردشة فيديو. في البداية، تحاول ICE ربط الأجهزة المشابهة مباشرةً بأقل وقت استجابة ممكن عبر بروتوكول UDP. في هذه العملية، لدى خوادم STUN مهمة واحدة: وهي تمكين أي زميل وراء NAT من معرفة عنوانها العام ومنفذها. (لمزيد من المعلومات حول STUN وخاتم التحول، يُرجى الاطّلاع على مقالة إنشاء خدمات الخلفية اللازمة لتطبيق WebRTC.

العثور على جهات الاتصال المرشحة
العثور على جهات الاتصال المرشحة

إذا تعذّر بروتوكول UDP، يحاول ICE الاتصال ببروتوكول TCP. في حال تعذُّر الاتصال المباشر، وخاصةً بسبب اجتياز بروتوكول NAT والجدار الناري للمؤسسة، تستخدم ICE خادمًا وسيطًا (للإرسال). بمعنى آخر، يستخدم ICE أولًا STUN مع UDP للاتصال بأقرانه مباشرةً، وفي حال فشل ذلك، يعود إلى خادم الإرسال turn. يشير التعبير العثور على العناصر المرشحة إلى عملية البحث عن واجهات الشبكة ومنافذها.

مسارات بيانات WebRTC
مسارات بيانات WebRTC

يقدّم مهندس WebRTC، "جاستن أوبيرتي"، المزيد من المعلومات حول ICE وSTUN وتحوّل في عرض تقديمي لمؤتمر Google I/O WebRTC لعام 2013. (تقدم الشرائح في العرض التقديمي أمثلة على عمليات تنفيذ خادم turn وSTUN.)

برنامج دردشة فيديو بسيط

يُعد العرض التوضيحي لمحادثة الفيديو على appr.tc مكانًا جيدًا لتجربة WebRTC، المكتمل بإرسال الإشارات واجتياز NAT/جدار الحماية باستخدام خادم STUN. يستخدم هذا التطبيق adapter.js، وهو عنصر رشيق لعزل التطبيقات عن التغييرات في المواصفات والاختلافات في البادئات.

الرمز مطول عمدًا في التسجيل. راجِع وحدة التحكّم لفهم ترتيب الأحداث. في ما يلي جولة تفصيلية للتعليمة البرمجية.

طوبولس الشبكة

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

مخطط طوبولوجي لوحدة التحكم المتعددة النقاط
مثال على طوبولوجيا وحدة التحكّم متعددة النقاط

لا تعرض العديد من تطبيقات WebRTC الحالية إلا الاتصال بين متصفِّحات الويب، ولكن يمكن لخوادم المدخل تفعيل تطبيق WebRTC قيد التشغيل على المتصفِّح للتفاعل مع الأجهزة، مثل الهواتف (المعروفة أيضًا باسم PSTN) وأنظمة VOIP. في أيار (مايو) 2012، أطلقت شركة Doubango Telecom برنامج sipml5 SIP Client الذي تم إنشاؤه باستخدام WebRTC وWebSocket والتي توفّر (من بين الاستخدامات المحتملة الأخرى) إمكانية إجراء مكالمات الفيديو بين المتصفحات والتطبيقات التي تعمل على نظامَي التشغيل iOS وAndroid. في مؤتمر Google I/O، عرضت "تيثر" و"تروبو" إطار عمل للاتصالات المتعلّقة بالكوارث في حقيبة باستخدام خلية OpenBTS لإتاحة الاتصالات بين الهواتف العادية وأجهزة الكمبيوتر من خلال WebRTC. اتصال هاتفي بدون مشغل شبكة!

عرض توضيحي لـ Tethr/Tropo في مؤتمر Google I/O 2012
تيثر/تروبو: الإبلاغ عن الكوارث في حقيبة

RTCDataChannel واجهة برمجة التطبيقات<

بالإضافة إلى الصوت والفيديو، تتيح WebRTC إمكانية الاتصال في الوقت الفعلي بالأنواع الأخرى من البيانات.

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

هناك العديد من حالات الاستخدام المحتمَلة لواجهة برمجة التطبيقات، بما في ذلك:

  • ألعاب فيديو
  • تطبيقات سطح المكتب البعيد
  • محادثة نصية في الوقت الفعلي
  • نقل الملفات
  • الشبكات اللامركزية

تتضمّن واجهة برمجة التطبيقات العديد من الميزات للاستفادة إلى أقصى حد من RTCPeerConnection وإتاحة التواصل بشكل فعّال ومرن من نظير إلى نظير:

  • الاستفادة من إعداد جلسة واحدة (RTCPeerConnection)
  • قنوات متعددة متزامنة مع منحها الأولوية
  • دلالات تسليم موثوقة وغير موثوق بها
  • ميزات الأمان المُدمَجة (DTLS) والتحكّم في تكدس البيانات
  • إمكانية استخدام المحتوى مع صوت أو فيديو أو بدونهما

تتشابه البنية بشكل مقصود مع WebSocket مع طريقة send() وحدث message:

const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
  localConnection.createDataChannel('sendDataChannel');

// ...

remoteConnection.ondatachannel = (event) => {
  receiveChannel = event.channel;
  receiveChannel.onmessage = onReceiveMessage;
  receiveChannel.onopen = onReceiveChannelStateChange;
  receiveChannel.onclose = onReceiveChannelStateChange;
};

function onReceiveMessage(event) {
  document.querySelector("textarea#send").value = event.data;
}

document.querySelector("button#send").onclick = () => {
  var data = document.querySelector("textarea#send").value;
  sendChannel.send(data);
};

يحدث الاتصال بين المتصفحات مباشرةً، لذا يمكن أن يكون RTCDataChannel أسرع بكثير من WebSocket حتى في حال الحاجة إلى خادم ترحيل (turn) عند تعذُّر فتح الثقب للتعامل مع جدران الحماية وترجمة عنوان الشبكة (NAT).

يتوفّر RTCDataChannel في Chrome وSafari وFirefox وOpera وSamsung Internet. تستخدم لعبة Cube Slam واجهة برمجة التطبيقات للإبلاغ عن حالة اللعبة. العب مع أحد أصدقائك أو تقمَّص شخصية الدب. أتاحت المنصة المبتكرة Sharefest مشاركة الملفات من خلال RTCDataChannel وpeerCDN، ما وفّر لمحة عن كيفية تفعيل WebRTC لتوزيع المحتوى من نظير لنظير.

لمزيد من المعلومات حول RTCDataChannel، يمكنك إلقاء نظرة على مواصفات بروتوكول المسودة في مجموعة مهندسي شبكة الإنترنت (IETF).

الأمان

هناك عدة طرق يمكن أن يعرِّض بها تطبيق أو مكون إضافي للاتصال في الوقت الفعلي الأمان للخطر. على سبيل المثال:

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

تحتوي WebRTC على العديد من الميزات لتجنُّب المشاكل التالية:

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

لن تتناول هذه المقالة مناقشة كاملة حول أمان بث الوسائط. لمزيد من المعلومات، يُرجى الاطّلاع على بنية أمان WebRTC المقترَحة التي اقترحتها مجموعة مهندسي شبكة الإنترنت (IETF).

الخلاصة

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

ليست التكنولوجيا أكثر تأثيرًا من ذلك.

بحسب المدون فيل إدهولم ، "من المحتمل أن يتمكن WebRTC وHTML5 من تمكين التحويل نفسه للاتصال في الوقت الفعلي الذي أجراه المتصفح الأصلي للحصول على المعلومات".

أدوات المطوّرين

مزيد من المعلومات

المعايير والبروتوكولات

ملخّص دعم WebRTC

واجهات برمجة التطبيقات MediaStream وgetUserMedia

  • الإصدار 18.0.1008 من Chrome لسطح المكتب أو الإصدارات الأحدث Chrome لنظام Android 29 والإصدارات الأحدث
  • Opera 18 والإصدارات الأحدث Opera لنظام التشغيل Android 20 والإصدارات الأحدث
  • Opera 12، Opera Mobile 12 (استنادًا إلى محرك Presto)
  • Firefox 17 والإصدارات الأحدث
  • Microsoft Edge 16 والإصدارات الأحدث
  • Safari 11.2 والإصدارات الأحدث على نظام التشغيل iOS والإصدار 11.1 والإصدارات الأحدث على نظام التشغيل MacOS
  • الإصدار 11.8 أو الإصدارات الأحدث من نظام التشغيل Android
  • الإنترنت 4 لأجهزة Samsung والإصدارات الأحدث

واجهة برمجة تطبيقات RTCPeerConnection

  • الإصدار 20 من Chrome Desktop والإصدارات الأحدث؛ Chrome لنظام التشغيل Android 29 والإصدارات الأحدث (بدون علم)
  • Opera 18 والإصدارات الأحدث (مفعّل تلقائيًا) Opera لنظام التشغيل Android 20 والإصدارات الأحدث (مفعّل تلقائيًا)
  • Firefox 22 والإصدارات الأحدث (مفعّل تلقائيًا)
  • Microsoft Edge 16 والإصدارات الأحدث
  • Safari 11.2 والإصدارات الأحدث على نظام التشغيل iOS والإصدار 11.1 والإصدارات الأحدث على نظام التشغيل MacOS
  • الإنترنت 4 لأجهزة Samsung والإصدارات الأحدث

واجهة برمجة تطبيقات RTCDataChannel

  • إصدار تجريبي في Chrome 25، ولكنه أكثر ثباتًا (وإمكانية التشغيل التفاعلي في Firefox) في Chrome 26 والإصدارات الأحدث؛ Chrome لنظام Android 29 والإصدارات الأحدث
  • إصدار ثابت (وإمكانية التشغيل التفاعلي في Firefox) في Opera 18 والإصدارات الأحدث؛ Opera لنظام التشغيل Android 20 والإصدارات الأحدث
  • Firefox 22 والإصدارات الأحدث (مفعّل تلقائيًا)

للحصول على معلومات أكثر تفصيلاً حول إتاحة واجهات برمجة التطبيقات من عدّة منصات، مثل getUserMedia وRTCPeerConnection، يمكنك الاطّلاع على caniuse.com وحالة النظام الأساسي Chrome.

تتوفر أيضًا واجهات برمجة التطبيقات الأصلية في RTCPeerConnection في المستندات على webrtc.org.