Google is committed to advancing racial equity for Black communities. See how.
หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

เริ่มต้นด้วยการเชื่อมต่อแบบเพียร์

การเชื่อมต่อแบบเพียร์เป็นส่วนหนึ่งของข้อกำหนด WebRTC ที่เกี่ยวข้องกับการเชื่อมต่อสองแอปพลิเคชันบนคอมพิวเตอร์ที่แตกต่างกันเพื่อสื่อสารโดยใช้โปรโตคอลเพียร์ทูเพียร์ การสื่อสารระหว่างเพื่อนสามารถเป็นวิดีโอเสียงหรือข้อมูลไบนารีโดยพลการ (สำหรับลูกค้าที่สนับสนุน RTCDataChannel API) เพื่อค้นหาวิธีการเชื่อมต่อสองเพียร์ลูกค้าทั้งสองจำเป็นต้องจัดเตรียมการกำหนดค่าเซิร์ฟเวอร์ ICE นี่เป็นทั้ง STUN หรือ TURN-server และบทบาทของพวกเขาคือการให้ตัวเลือก ICE แก่ลูกค้าแต่ละรายซึ่งจะถูกถ่ายโอนไปยังเพียร์ระยะไกล การถ่ายโอนของผู้สมัคร ICE นี้โดยทั่วไปเรียกว่าการส่งสัญญาณ

การส่งสัญญาณ

ข้อมูลจำเพาะ WebRTC มี API สำหรับการสื่อสารกับเซิร์ฟเวอร์ ICE (การเชื่อมต่ออินเทอร์เน็ต) แต่องค์ประกอบการส่งสัญญาณไม่ได้เป็นส่วนหนึ่งของมัน จำเป็นต้องมีการส่งสัญญาณเพื่อให้เพื่อนสองคนแบ่งปันวิธีที่พวกเขาควรเชื่อมต่อ โดยปกติสิ่งนี้จะถูกแก้ไขผ่าน Web API ที่ใช้ 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 เดียวเป็นพารามิเตอร์ วัตถุนี้กำหนดวิธีการตั้งค่าการเชื่อมต่อเพียร์และควรมีข้อมูลเกี่ยวกับเซิร์ฟเวอร์ 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 ย่อมาจาก Session Traversal Utilities สำหรับ NAT และมักจะใช้ทางอ้อมในแอปพลิเคชัน WebRTC ส่วนใหญ่

TURN (Traversal Using Relay NAT) เป็นโซลูชั่นขั้นสูงที่รวมโปรโตคอล STUN และบริการ WebRTC เชิงพาณิชย์ส่วนใหญ่ใช้เซิร์ฟเวอร์ TURN เพื่อสร้างการเชื่อมต่อระหว่างเพื่อน WebRTC API รองรับทั้ง STUN และ TURN โดยตรงและถูกรวบรวมภายใต้คำว่าการจัดตั้งการเชื่อมต่ออินเทอร์เน็ตที่สมบูรณ์ยิ่งขึ้น เมื่อสร้างการเชื่อมต่อ WebRTC เรามักจะให้เซิร์ฟเวอร์ ICE หนึ่งหรือหลายตัวในการกำหนดค่าสำหรับวัตถุ RTCPeerConnection

Trickle ICE

เมื่อสร้างวัตถุ RTCPeerConnection เฟรมเวิร์กพื้นฐานจะใช้เซิร์ฟเวอร์ ICE ที่ให้มาเพื่อรวบรวมผู้สมัครสำหรับการสร้างการเชื่อมต่อ (ICE candidate) เหตุการณ์ 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 API