开始使用对等连接

对等连接是 WebRTC 规范的一部分,用于处理 将不同计算机上的两个应用连接起来, 对等连接协议。对等体之间的通信可以是视频、音频或 任意二进制数据(适用于支持 RTCDataChannel API 的客户端)。在 为了解两个对等方如何连接,两个客户端都需要提供 ICE 服务器配置。这是 STUN 或 TURN 服务器,其角色为 为每个客户端提供 ICE 候选对象,然后将其传输到远程 对等设备这种 ICE 候选项的传输通常称为信号。

信令

WebRTC 规范包含用于与 ICE(互联网 连接建立)服务器,但信号组件不属于 。只有发送信号后,两位对等方才能分享应该如何连接。 这通常通过基于 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 候选人

两位对等方在使用 WebRTC 进行交流之前,需要先 网络连接信息由于网络条件可能会因 外部服务通常用于发现 可能的候选连接。此服务称为 ICE, 使用 STUN 或 TURN 服务器。STUN 是“会话遍历”的缩写。 NAT 实用程序,通常间接用于大多数 WebRTC 应用。

TURN(使用中继 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 候选对象后,我们应该会预料到对等方的状态。 连接最终会变为已连接状态。为了检测这一点,我们添加了一个 我们的 RTCPeerConnection 的监听器,用于监听 connectionstatechange 事件。

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

RTCPeerConnection API 文档