Google is committed to advancing racial equity for Black communities. See how.
דף זה תורגם על ידי Cloud Translation API.
Switch to English

תחילת העבודה עם חיבורי עמיתים

חיבורי עמיתים הוא החלק של מפרטי WebRTC העוסק בחיבור שני יישומים במחשבים שונים לתקשורת באמצעות פרוטוקול עמיתים לעמית. התקשורת בין עמיתים יכולה להיות מידע וידאו, אודיו או נתונים בינאריים שרירותיים (עבור לקוחות התומכים בממשק ה- API של RTCDataChannel ). על מנת לגלות כיצד שני עמיתים יכולים להתחבר, שני הלקוחות צריכים לספק תצורת שרת ICE. זהו STUN או שרת TURN, ותפקידם לספק מועמדי ICE לכל לקוח אשר מועבר אחר כך לעמית העמוק המרוחק. העברה זו של מועמדי ICE נקראת בדרך כלל איתות.

איתות

מפרט ה- WebRTC כולל ממשקי API לתקשורת עם שרת ICE (הקמת קישוריות לאינטרנט), אך רכיב האיתות אינו חלק ממנו. יש צורך באיתות כדי ששני בני גילם יוכלו לשתף כיצד הם צריכים להתחבר. בדרך כלל זה נפתר באמצעות ממשק אינטרנט רגיל מבוסס HTTP מבוסס אינטרנט (כלומר, שירות REST או מנגנון RPC אחר) בו יישומי אינטרנט יכולים להעביר את המידע הדרוש לפני חיבור העמיתים.

קטע הקוד הבא מראה כיצד ניתן להשתמש בשירות איתות פיקטיבי זה כדי לשלוח ולקבל הודעות בצורה סינכרונית. זה ישמש בדוגמאות שנותרו במדריך זה במידת הצורך.

 // 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 למחלקה זו לוקח אובייקט RTCConfiguration יחיד 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 מופע ה- 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 בכל עמית ולהעביר (דרך ערוץ האיתות) לעמית האחר.

מועמדי קרח

לפני ששני עמיתים יכולים להתחבר באמצעות WebRTC, הם צריכים להחליף מידע קישוריות. מכיוון שתנאי הרשת יכולים להשתנות בהתאם למספר גורמים, שירות חיצוני משמש בדרך כלל לגילוי המועמדים האפשריים להתחברות לעמית. שירות זה נקרא ICE ומשתמש בשרת STUN או בשרת TURN. STUN מייצג Session Traversal Utilities עבור NAT, ומשמש בדרך כלל בעקיפין ברוב יישומי WebRTC.

TURN (Traversal Using Relay NAT) הוא הפיתרון המתקדם יותר המשלב את פרוטוקולי STUN והשירותים המסחריים ביותר המבוססים על WebRTC משתמשים בשרת TURN לצורך יצירת חיבורים בין עמיתים. ממשק ה- API של WebRTC תומך ישירות ב- STUN וגם ב- TURN, והוא נאסף תחת המונח השלם יותר לקישור קישוריות לאינטרנט. בעת יצירת חיבור WebRTC, אנו בדרך כלל מספקים שרתי ICE אחד או מספר בתצורה עבור אובייקט RTCPeerConnection .

טריק 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);
        }
    }
});
 

נוצר חיבור

ברגע שמתקבלים מועמדי קרח, עלינו לצפות כי המדינה שהקשר העמיתים שלנו ישתנה בסופו של דבר למדינה מחוברת. כדי לזהות זאת, אנו מוסיפים מאזין ל- RTCPeerConnection שלנו, שם אנו מאזינים connectionstatechange לאירועים RTCPeerConnection .

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

תיעוד ממשק API של RTCPeerConnection