開始使用對等連線

對等互連連線是 WebRTC 規格的一部分, 連線兩個應用程式,以使用不同電腦進行通訊 點對點通訊協定同業之間的通訊可以是視訊、音訊或 任意二進位資料 (用於支援 RTCDataChannel API 的用戶端)。於 為了瞭解兩位同業如何溝通交流,兩位客戶都必須提供 ICE 伺服器設定。這可能是 STUN 或 TURN 伺服器,而他們的角色是 為每位用戶端提供 ICE 候選項目,接著再轉移至遠端 。此次轉移 ICE 候選人的行為通常稱為「信號」。

訊號

WebRTC 規格包含用於與 ICE (網際網路) 通訊的 API 連線能力建立) 伺服器,但信號元件不屬於 基礎架構必須要有信號,兩個同業才能分享聯絡方式。 通常是透過一般的 HTTP 型 Web API (即 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,才能搭配使用 WebRTC 以及網路連線資訊由於網路狀況可能不同 通常用於找出 可能連線至對等點。這項服務稱為 ICE, 使用 STUN 或 TURN 伺服器。STUN 代表 Session Traversal NAT 的公用程式,通常間接用於大部分的 WebRTC 應用程式。

TURN (使用 Relay NAT 進行遍歷) 是比較進階的解決方案, STUN 通訊協定和大部分商業 WebRTC 型服務都使用 TURN 伺服器 建立對等點之間的連線。WebRTC API 同時支援 STUN 而且透過更完整的網際網路系統收集的資料 建立連線。在建立 WebRTC 連線時 請在「網頁設定」中 RTCPeerConnection 物件。

幻彩小球

建立 RTCPeerConnection 物件後,基礎架構會使用 已提供 ICE 伺服器來收集訂房機構 (ICE) 的候選名單 候選項目)。RTCPeerConnection 個信號的事件 icegatheringstatechange 處於 ICE 收集作業的狀態 (newgatheringcomplete)。

雖然同儕可以等到 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 候選人後,我們應會預期同儕的州別 連線後就會變更為連線狀態為了偵測這種情況,我們加入了 監聽 connectionstatechangeRTCPeerConnection 事件。

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

RTCPeerConnection API 說明文件