เริ่มต้นใช้งานการเชื่อมต่อเพียร์

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

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

ข้อกำหนด WebRTC จะรวม API สำหรับการสื่อสารกับ ICE (Internet) การสร้างการเชื่อมต่อ) เซิร์ฟเวอร์ แต่คอมโพเนนต์การส่งสัญญาณไม่ได้เป็นส่วนหนึ่งของ ได้ จำเป็นต้องมีการส่งสัญญาณเพื่อให้เพื่อนร่วมงาน 2 ฝ่ายได้แชร์ว่าแต่ละฝ่ายควรเชื่อมต่อกันอย่างไร โดยทั่วไปปัญหานี้แก้ไขได้ด้วย 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});
    }
});

เมื่อทั้ง 2 แอปเทียบเท่าได้กำหนดคำอธิบายของเซสชันทั้งภายในและระยะไกลแล้ว ทราบถึงความสามารถของเครื่องระยะไกล ซึ่งไม่ได้หมายความว่าการเชื่อมต่อ ระหว่างแอปเทียบเท่าได้ เราจำเป็นต้องรวบรวม ICE จึงจะใช้งานได้ ผู้สมัครในระดับเดียวกันและโอน (ผ่านช่องส่งสัญญาณ) ไปยังอีกฝ่าย ที่คล้ายกัน

ผู้สมัครรับเลือกตั้ง ICE

ก่อนที่แอปเทียบเท่า 2 รายจะสื่อสารกันได้โดยใช้ WebRTC ลูกค้าต้องแลกเปลี่ยนกัน ข้อมูลการเชื่อมต่อ เนื่องจากเงื่อนไขของเครือข่ายอาจแตกต่างกันไป บริการภายนอกมักจะใช้เพื่อค้นหา ที่อาจใช้เพื่อเชื่อมต่อกับเพื่อน บริการนี้เรียกว่า ICE และ โดยใช้เซิร์ฟเวอร์ STUN หรือ TURN STUN ย่อมาจาก Session Traversal ยูทิลิตีสำหรับ NAT และมักจะใช้โดยอ้อมในแอปพลิเคชัน WebRTC ส่วนใหญ่

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

เสียง ICE คลื่น

เมื่อสร้างออบเจ็กต์ RTCPeerConnection แล้ว เฟรมเวิร์กที่สำคัญจะใช้เมธอด จัดหาเซิร์ฟเวอร์ ICE ให้รวบรวมผู้สมัครสำหรับการสร้างการเชื่อมต่อ (ICE ตัวเลือก) เหตุการณ์ icegatheringstatechange ใน RTCPeerConnection สัญญาณ การรวบรวม ICE อยู่ในสถานะใด (new, gathering หรือ complete)

แม้ว่าเพียร์จะรอให้การรวบรวม ICE เสร็จสมบูรณ์ได้ แต่ มักจะมีประสิทธิภาพดีกว่าการใช้ "น้ำแข็งระเหย" เทคนิคและการส่งข้อมูล ตัวเลือก ICE แต่ละรายการไปยังเครื่องระยะไกลเมื่อตรวจพบ การดำเนินการนี้จะ ลดเวลาในการตั้งค่าสำหรับการเชื่อมต่อระหว่างเครื่องได้อย่างมากและอนุญาตให้ใช้วิดีโอได้ การโทรเพื่อเริ่มต้นโดยมีความล่าช้าน้อยลง

หากต้องการรวบรวมตัวเลือก ICE เพียงเพิ่ม Listener สำหรับกิจกรรม icecandidate RTCPeerConnectionIceEvent ที่ปล่อยออกมาใน Listener นั้นจะประกอบด้วย พร็อพเพอร์ตี้ 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 เอกสารประกอบ