بدء استخدام WebRTC

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

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

التواصل في الوقت الفعلي بدون إضافات

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

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

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

البدء بسرعة

هل ليس لديك الوقت الكافي لقراءة هذه المقالة أو تريد الحصول على الرمز فقط؟

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

لمحة قصيرة جدًا عن WebRTC

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

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

أصبحت مكالمات الفيديو في Gmail شائعة في عام 2008، وفي عام 2011، طرحت Google تطبيق Hangouts الذي يستخدم Talk (مثل Gmail). اشترت Google شركة GIPS، وهي شركة طوّرت العديد من المكوّنات المطلوبة لاستخدام بروتوكول RTC، مثل برامج الترميز وأساليب إلغاء الصدى. ولقد أتاحت Google استخدام التقنيات التي طوّرها فريق GIPS، كما تعاونت مع الهيئات المعنية بالمعايير في مجموعة مهندسي شبكة الإنترنت (IETF) واتحاد شبكة الويب العالمية (W3C) لضمان توافق الصناعة. في أيار (مايو) 2011، أنشأت شركة Ericsson أول عملية تنفيذ لخدمة 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 Peer connection وappr.tc، على التوالي. يستخدم هذا التطبيق adapter.js، وهو واجهة برمجة تطبيقات JavaScript تديرها Google بمساعدة منتدى WebRTC، لتجاهل الاختلافات بين المتصفّحات وتغييرات المواصفات.

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

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

أول استخدام لك لخدمة WebRTC

يجب أن تُجري تطبيقات WebRTC عدة إجراءات:

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

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

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

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

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

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

إنّ أسهل طريقة لفهم واجهة برمجة التطبيقات MediaStream هي الاطّلاع عليها في الواقع:

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

يحتوي كل MediaStream على إدخال، قد يكون MediaStream تم إنشاؤه بواسطة getUserMedia()، ومخرجات، قد يتم تمريرها إلى عنصر فيديو أو RTCPeerConnection.

تأخذ طريقة getUserMedia() مَعلمة عنصر MediaStreamConstraints وتُعرِض Promise التي يتمّ حلّها إلى عنصر MediaStream.

يحتوي كلّ MediaStream على label، مثل 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'. تُعرِض الطريقتان getAudioTracks() وgetVideoTracks() صفيفًا من MediaStreamTrack.

في مثال 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);
});

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

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

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

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

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

القيود

يمكن استخدام القيود لضبط قيم درجة دقة الفيديو في 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(). يُرجى العلم أيضًا أنّه في Chrome وOpera، يتم حاليًا إضافة البادئة RTCPeerConnection.

// 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()، ويمرّر إليها الوصف عن بُعد الذي حصل عليه من "أليسا" حتى يمكن إنشاء جلسة محلية متوافقة مع جلستها. يتم تمرير RTCSessionDescription إلى دالة ردّ الاتصال createAnswer(). يضبط "بوب" ذلك على أنّه الوصف المحلي ويرسله إلى "أليسا".
  5. عندما تتلقّى "ليلى" وصف جلسة "بدر"، تحدّده كوصف عن بُعد باستخدام setRemoteDescription.
  6. مرحبًا،

عناصر RTCSessionDescription هي مجموعات بيانات تتّبع بروتوكول وصف الجلسة. بعد التسلسل، يظهر عنصر 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 لأول مرة).

مخطّط JSEP البياني للبنية
بنية JSEP

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

RTCPeerConnection

RTCPeerConnection هو مكوّن WebRTC الذي يعالج الاتصالات الثابتة والفعّالة لبيانات البث بين الأجهزة المشابهة.

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

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

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

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

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

RTCPeerConnection بدون خوادم

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

في هذا المثال، يمثّل pc1 المضيف المحلي (المتصل) ويمثّل pc2 المضيف البعيد (المُتصل به).

المُتصِل

  1. أنشئ RTCPeerConnection جديدًا وأضِف البث من getUserMedia(): ```js // Servers هو ملف إعدادات اختياري. (راجِع مناقشة TURN وSTUN لاحقًا.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { 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 إلى أربعة أنواع من الوظائف من جهة الخادم:

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

لا يتناول هذا المقال عبور جدار الحماية (NAT) والشبكات من نظير إلى نظير ومتطلبات إنشاء تطبيق خادم لاكتشاف المستخدمين وإرسال الإشارات إليهم. يكفي القول إنّ إطار عمل ICE يستخدم بروتوكول STUN وإضافة TURN لتمكين RTCPeerConnection من التعامل مع عبور NAT والمشاكل الأخرى في الشبكة.

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

العثور على تطبيقات مؤهّلة للربط
العثور على حسابات مؤهّلة للربط

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

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

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

برنامج بسيط لمحادثات الفيديو

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

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

تصاميم الشبكات

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

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

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

عرض توضيحي لـ Tethr/Tropo في مؤتمر Google I/O لعام 2012
Tethr/Tropo: Disaster communications in a briefcase

RTCDataChannel API<

بالإضافة إلى الصوت والفيديو، يتيح 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 التحويل نفسه للتواصل في الوقت الفعلي الذي يوفّره المتصفّح الأصلي للمعلومات".

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

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

  • جلسة Justin Uberti حول WebRTC في مؤتمر Google I/O لعام 2012
  • كمال جونستون ودانيل سي ينشر "بيرنت" كتابًا عن WebRTC في طبعته الثالثة بتنسيقَي الكتاب المطبوع والكتاب الإلكتروني على الرابط webrtcbook.com.
  • يقدّم الموقع الإلكتروني webrtc.org كل ما يتعلّق بتكنولوجيا WebRTC، بما في ذلك العروض التوضيحية والمستندات والمناقشات.
  • discuss-webrtc هي مجموعة على Google لمناقشة المواضيع الفنية حول WebRTC.
  • @webrtc
  • تقدّم مستندات Talk لمطوّري تطبيقات Google مزيدًا من المعلومات حول عبور جدار الحماية (NAT) وبروتوكول STUN وخوادم الإعادة وجمع المرشحين.
  • WebRTC على GitHub
  • Stack Overflow هو مكان جيد للبحث عن إجابات وطرح أسئلة حول WebRTC.

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

ملخّص دعم WebRTC

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

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

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

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

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

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

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

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