Bắt đầu kết nối với ứng dụng ngang hàng

Kết nối ngang hàng là một phần trong thông số kỹ thuật WebRTC liên quan đến kết nối hai ứng dụng trên các máy tính khác nhau để giao tiếp bằng một giao thức ngang hàng. Giao tiếp giữa các ứng dụng ngang hàng có thể là video, âm thanh hoặc dữ liệu nhị phân tuỳ ý (dành cho các ứng dụng hỗ trợ API RTCDataChannel). Trong để khám phá cách hai người dùng ngang hàng có thể kết nối với nhau, cả hai khách hàng cần cung cấp ICE Cấu hình máy chủ. Đây là STUN hoặc máy chủ TURN và vai trò của chúng là để cung cấp các ứng viên ICE cho từng khách hàng, sau đó được chuyển đến điều khiển từ xa ứng dụng ngang hàng. Việc chuyển các ứng viên ICE thường được gọi là báo hiệu.

Tín hiệu

Thông số kỹ thuật của WebRTC bao gồm cả API để giao tiếp với ICE (Internet) Máy chủ Thiết lập kết nối), nhưng thành phần tín hiệu không thuộc nó. Cần có tín hiệu để hai ứng dụng ngang hàng có thể chia sẻ cách kết nối với nhau. Việc này thường được giải quyết thông qua Web API dựa trên HTTP thông thường (ví dụ: REST) hoặc cơ chế RPC khác) nơi các ứng dụng web có thể chuyển tiếp dữ liệu cần thiết trước khi khởi tạo kết nối ngang hàng.

Đoạn mã sau đây minh hoạ cách sử dụng dịch vụ tín hiệu ảo này để gửi và nhận thư một cách không đồng bộ. Thông tin này sẽ được dùng trong phần còn lại ví dụ trong hướng dẫn này nếu cần.

// 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!');

Hoạt động tín hiệu có thể được triển khai theo nhiều cách và WebRTC không thích bất kỳ giải pháp cụ thể nào.

Đang khởi tạo kết nối ngang hàng

Mỗi kết nối ngang hàng do một đối tượng RTCPeerConnection xử lý. Hàm khởi tạo cho lớp này sẽ lấy một đối tượng RTCConfiguration duy nhất làm tham số. Chiến dịch này đối tượng xác định cách thiết lập kết nối ngang hàng và chứa thông tin về máy chủ ICE sử dụng.

Sau khi tạo RTCPeerConnection, chúng ta cần tạo một ưu đãi SDP hoặc trả lời, tuỳ thuộc vào việc chúng ta là ứng dụng ngang hàng gọi hay nhận cuộc gọi ngang hàng. Sau khi SDP thì đề nghị hoặc câu trả lời phải được gửi tới ứng dụng ngang hàng từ xa thông qua kênh khác. Việc truyền đối tượng SDP đến các ứng dụng ngang hàng từ xa được gọi là báo hiệu và không thuộc phạm vi điều chỉnh của thông số kỹ thuật WebRTC.

Để bắt đầu thiết lập kết nối ngang hàng từ phía gọi, chúng ta tạo một RTCPeerConnection, sau đó gọi createOffer() để tạo một Đối tượng RTCSessionDescription. Nội dung mô tả phiên này được đặt làm phiên bản cục bộ mô tả bằng setLocalDescription(), sau đó được gửi qua tín hiệu của chúng tôi kênh sang bên nhận. Chúng ta cũng thiết lập một trình nghe tín hiệu kênh cho biết khi nhận được câu trả lời cho nội dung mô tả phiên sự kiện do chúng tôi cung cấp bên nhận.

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});
}

Ở phía người nhận, chúng ta sẽ đợi một đề nghị được gửi đến trước khi tạo Thực thể RTCPeerConnection. Sau khi hoàn tất, chúng ta đặt ưu đãi nhận được bằng cách sử dụng setRemoteDescription(). Tiếp theo, chúng ta gọi createAnswer() để tạo câu trả lời cho ưu đãi đã nhận được. Câu trả lời này được đặt làm nội dung mô tả địa phương bằng cách sử dụng setLocalDescription(), sau đó gửi đến bên gọi qua tín hiệu của chúng tôi máy chủ.

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});
    }
});

Sau khi 2 ứng dụng ngang hàng đặt cả phần mô tả phiên cục bộ lẫn từ xa, chúng biết khả năng của ứng dụng ngang hàng từ xa. Điều này không có nghĩa là kết nối giữa các ứng dụng ngang hàng. Để làm được điều này, chúng ta cần thu thập ICE ứng viên ở mỗi ứng dụng ngang hàng và chuyển (qua kênh báo hiệu) sang ứng dụng khác ứng dụng ngang hàng.

Ứng cử viên ICE

Trước khi hai người dùng ngang hàng có thể cộng tác bằng WebRTC, họ cần trao đổi thông tin về khả năng kết nối. Do điều kiện mạng có thể thay đổi tuỳ thuộc vào yếu tố, một dịch vụ bên ngoài thường được sử dụng để phát hiện khả năng kết nối với đồng nghiệp. Dịch vụ này được gọi là ICE và bằng cách sử dụng máy chủ STUN hoặc TURN. STUN là viết tắt của Session Traversal Tiện ích cho NAT và thường được sử dụng gián tiếp trong hầu hết các ứng dụng WebRTC.

TURN (Chuyển bằng cách sử dụng NAT Chuyển tiếp) là giải pháp nâng cao hơn kết hợp các giao thức STUN và hầu hết các dịch vụ dựa trên WebRTC thương mại đều sử dụng máy chủ TURN để thiết lập kết nối giữa các ứng dụng ngang hàng. API WebRTC hỗ trợ cả STUN và TURN, và thông tin này được tập hợp dưới thuật ngữ đầy đủ hơn là Internet Thiết lập khả năng kết nối. Khi tạo kết nối WebRTC, chúng tôi thường cung cấp một hoặc nhiều máy chủ ICE trong cấu hình cho Đối tượng RTCPeerConnection.

Mạch nước chảy

Sau khi một đối tượng RTCPeerConnection được tạo, khung cơ bản sẽ sử dụng cung cấp máy chủ ICE để tập hợp các ứng viên cho việc thiết lập liên kết thông tin (ICE) ứng cử viên). Sự kiện icegatheringstatechange trên RTCPeerConnection tín hiệu tại trạng thái thu thập ICE (new, gathering hoặc complete).

Mặc dù bạn có thể phải đợi cho đến khi quá trình thu thập ICE hoàn tất, nhưng thường hiệu quả hơn nhiều khi sử dụng "đá lừa" kỹ thuật và truyền từng ứng viên ICE đến ứng dụng ngang hàng từ xa khi nó được phát hiện. Thao tác này sẽ giảm đáng kể thời gian thiết lập kết nối ngang hàng và cho phép phát video để bắt đầu ít chậm trễ hơn.

Để thu thập các đề xuất ICE, bạn chỉ cần thêm một trình nghe cho sự kiện icecandidate. RTCPeerConnectionIceEvent được phát ra trên trình nghe đó sẽ chứa Thuộc tính candidate đại diện cho một ứng viên mới sẽ được gửi đến ngang hàng từ xa (Xem Tín hiệu).

// 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);
        }
    }
});

Đã thiết lập kết nối

Sau khi nhận được các ứng cử viên ICE, chúng ta sẽ chờ đợi trạng thái của các ứng viên ngang hàng kết nối sẽ chuyển sang trạng thái được kết nối. Để phát hiện điều này, chúng tôi thêm một trình nghe RTCPeerConnection của chúng tôi, tại đó chúng tôi lắng nghe connectionstatechange các sự kiện.

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

API RTCPeerConnection tài liệu