بدء استخدام اتصالات الزملاء

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

الإشارة

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

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

// Set up an asynchronous communication channel that will be
// used during the peer connection setup
const signalingChannel = new SignalingChannel(remoteClientId);
signalingChannel.addEventListener('message', message => {
    // New message from remote client received
});

// Send an asynchronous message to the remote client
signalingChannel.send('Hello!');

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

بدء اتصالات الزملاء

يتعامل عنصر RTCPeerConnection مع كل اتصال نظير. الدالة الإنشائية في هذه الفئة، يتم استخدام كائن RTCConfiguration واحد كمَعلمته. هذا النمط يحدد كيفية إعداد اتصال النظير ويجب أن يحتوي على معلومات لخوادم ICE.

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

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

async function makeCall() {
    const configuration = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]}
    const peerConnection = new RTCPeerConnection(configuration);
    signalingChannel.addEventListener('message', async message => {
        if (message.answer) {
            const remoteDesc = new RTCSessionDescription(message.answer);
            await peerConnection.setRemoteDescription(remoteDesc);
        }
    });
    const offer = await peerConnection.createOffer();
    await peerConnection.setLocalDescription(offer);
    signalingChannel.send({'offer': offer});
}

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

const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener('message', async message => {
    if (message.offer) {
        peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
        const answer = await peerConnection.createAnswer();
        await peerConnection.setLocalDescription(answer);
        signalingChannel.send({'answer': answer});
    }
});

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

مرشّحو ICE

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

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

Trickle ICE

بعد إنشاء عنصر RTCPeerConnection، يستخدم إطار العمل الأساسي تقديم خوادم ICE لجمع المرشحين لإنشاء إمكانية الاتصال (ICE المرشحين). الحدث icegatheringstatechange في إشارات RTCPeerConnection حسب حالة جمع ICE (new أو gathering أو complete).

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

لجمع مرشّحين من ICE، ما عليك سوى إضافة أداة استماع إلى حدث "icecandidate". ستتضمّن قيمة RTCPeerConnectionIceEvent المنبعثة من ذلك المستمع السمة candidate التي تمثّل مرشحًا جديدًا يجب إرساله إلى نظير بعيد (راجِع الإشارة).

// Listen for local ICE candidates on the local RTCPeerConnection
peerConnection.addEventListener('icecandidate', event => {
    if (event.candidate) {
        signalingChannel.send({'new-ice-candidate': event.candidate});
    }
});

// Listen for remote ICE candidates and add them to the local RTCPeerConnection
signalingChannel.addEventListener('message', async message => {
    if (message.iceCandidate) {
        try {
            await peerConnection.addIceCandidate(message.iceCandidate);
        } catch (e) {
            console.error('Error adding received ice candidate', e);
        }
    }
});

تم إنشاء اتصال

فور تلقّي المرشحين لمركز ICE، علينا أن نتوقّع أن يحصل أي من الطرفين على الولاية سوف يتغير الاتصال في النهاية إلى حالة متصل. لاكتشاف ذلك، نضيف المستمع إلى RTCPeerConnection حيث نستمع إلى connectionstatechange أحداث.

// Listen for connectionstatechange on the local RTCPeerConnection
peerConnection.addEventListener('connectionstatechange', event => {
    if (peerConnection.connectionState === 'connected') {
        // Peers connected!
    }
});

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