بدء استخدام WebRTC

خدمة WebRTC هي واجهة جديدة في الحرب الطويلة على شبكة الويب المفتوحة وبدون قلق.

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

التواصل في الوقت الفعلي بدون مكوّنات إضافية

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

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

  1. افتح appr.tc في المتصفّح.
  2. انقر على انضمام للانضمام إلى غرفة محادثة والسماح للتطبيق باستخدام كاميرا الويب.
  3. افتح عنوان URL المعروض في نهاية الصفحة في علامة تبويب جديدة، أو من الأفضل فتح عنوان 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 لاتصال النظراء وappr.tc، على التوالي. يستخدم هذا التطبيق adapter.js، وهو مخطّط JavaScript تديره Google بمساعدة من منتدى WebRTC لإزالة الاختلافات والتغييرات في المواصفات في المتصفّح.

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

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

أول WebRTC

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

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

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

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

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

MediaStream API (المعروفة أيضًا باسم 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(). في المرة الأولى، يظهر زر "السماح" في شريط معلومات المتصفّح. تم إيقاف وصول HTTP إلى getUserMedia() من قِبل Chrome في نهاية عام 2015 بسبب تصنيفه كـ ميزة قوية.

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

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

  • Webcam Toy هو تطبيق صور يستخدم WebGL لإضافة تأثيرات غريبة ورائعة إلى الصور التي يمكن مشاركتها أو حفظها محليًا.
  • FaceKat هي لعبة لتتبُّع الوجوه تم تصميمها باستخدام headtrackr.js.
  • تستخدم كاميرا ASCII واجهة برمجة التطبيقات Canvas لإنشاء صور ASCII.
صورة ASCII تم إنشاؤها بواسطة idevelop.ro/acii-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 API.

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

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

  • رسائل التحكّم في الجلسة: لإعداد الاتصال أو إغلاقه والإبلاغ عن الأخطاء.
  • تهيئة الشبكة: بالنسبة إلى العالم الخارجي، ما عنوان IP ومنفذ 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. تشغِّل نبيلة طريقة createOffer() RTCPeerConnection. تم تمرير الناتج من هذه القيمة إلى RTCSessionDescription - وصف جلسة نبيلة المحلية.
  2. في طلب معاودة الاتصال، تضبط نبيلة الوصف المحلي باستخدام setLocalDescription()، ثم تُرسِل وصف الجلسة هذه إلى يوسف من خلال قناة الإشارات. يُرجى العلم أنّ ميزة "RTCPeerConnection" لن تبدأ في جمع المرشحين حتى يتم استدعاء "setLocalDescription()". وقد تم تدوين ذلك في مسودة JSEP IETF.
  3. يحدّد خالد الوصف الذي أرسلته نبيلة إليه كوصف عن بُعد باستخدام setRemoteDescription().
  4. يستخدم أمجد طريقة createAnswer() RTCPeerConnection، ويتمرير الوصف عن بُعد الذي حصل عليه من نبيلة بحيث يمكن إنشاء جلسة محلية متوافقة مع جلستها المحلية. اجتازت معاودة الاتصال بالرقم 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 لأول مرة.)

مخطط بنية JSEP
بنية 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 // الخوادم هو ملف إعداد اختياري. (راجع مناقشة tid وSTUN لاحقًا.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEvery((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 إلى أربعة أنواع من الوظائف من جهة الخادم:

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

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

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

العثور على المرشحين للاتصال
العثور على المرشحين للتواصل

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

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

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

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

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

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

مخططات الشبكة

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

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

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

عرض Tethr/Tropo في مؤتمر Google I/O 2012
Tothr/Tropo: التواصل في حالات الكوارث في حقيبة أوراق

واجهة برمجة تطبيقات 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) مطلوبًا عند استخدام الثقب للتعامل مع جدران الحماية وNATs.

تتوفّر 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

  • إصدار Chrome سطح المكتب 18.0.1008 والإصدارات الأحدث، و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
  • UC 11.8 والإصدارات الأحدث على Android
  • Samsung Internet 4 والإصدارات الأحدث

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

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

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

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

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

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