对等连接

RTCPeerConnection 是 WebRTC API 中的中心接口。它表示本地对等方与远程对等方之间的连接,并提供建立连接所需的所有函数和事件。

建立对等连接

实现 WebRTC 功能的应用通常会严重依赖 RTCPeerConnection 接口。从调用方(即发起连接的对等方)的角度来看,建立连接的过程通常如下所示:

  1. 使用适当的 ICE 配置创建新的 RTCPeerConnection 实例。
  2. 使用 RTCPeerConnection.createOffer() 创建本地 SDP 说明。
  3. 使用 RTCPeerConnection.setLocalDescription() 设置本地 SDP 说明。
  4. 通过信令服务将本地 SDP 说明传输到远程对等方。
  5. RTCPeerConnection 上的 icecandidate 事件注册监听器。
  6. 对于每个 icecandidate 事件,将其(使用信令服务)传输到远程对等方。
  7. 等待来自信令服务的传入远程 SDP 说明,并使用 RTCPeerConnection.setRemoteDescription() 设置该说明。
  8. 等待来自信令服务的传入远程 ICE 候选对象,并使用 RTCPeerConnection.addIceCandidate() 添加这些候选对象

在被调用方,流程略有不同。

  1. 使用适当的 ICE 配置创建新的 RTCPeerConnection 实例。
  2. 等待来自信令服务的传入远程 SDP 说明,并使用 RTCPeerConnection.setRemoteDescription() 设置该说明。
  3. 通过调用 RTCPeerConnection.createAnswer() 为远程 SDP 说明创建回答。
  4. 使用信令服务将回答转移到远程对等方。
  5. RTCPeerConnection 上的 icecandidate 事件注册监听器。
  6. 对于每个 icecandidate 事件,将其(使用信令服务)传输到远程对等方。
  7. 等待来自信令服务的传入远程 ICE 候选对象,并使用 RTCPeerConnection.addIceCandidate() 添加这些候选对象

此 API 的问题在于,其中大多数操作都是异步的,这通常会使 WebRTC 应用的实际实现变得复杂。许多函数都会返回 Promise,必须先解决此问题,才能继续执行流程中的下一步。

建议开发者在使用此 API 实现应用时,使用 asyncawait 而不是注册监听器(使用 Promise.then()),因为这样可以使代码更易于理解。请参考以下示例:

function createAndSendOffer(peerConnection, signallingService) {
    peerConnection.createOffer()
                  .then(offer => {
                      signallingService.send({
                          type: 'offer',
                          data: offer
                      });
                  });
}

使用 asyncawait 编写上述代码时,我们会得到以下结果:

async function createAndSendOffer(peerConnection, signallingService) {
    const offer = await peerConnection.createOffer();
    signallingService.send({
        type: 'offer',
        data: offer
    });
}