RTCPeerConnection: setRemoteDescription() 方法

Baseline 已广泛支持

此功能已成熟,可跨多种设备和浏览器版本使用。自 2017 年 9 月以来,它已在浏览器中提供。

RTCPeerConnection 接口的 setRemoteDescription() 方法将指定的会话描述设置为远程对等方的当前 offer 或 answer。该描述指定了连接远程端的属性,包括媒体格式。该方法接受一个参数——会话描述,并返回一个 Promise,该 Promise 在描述更改后异步完成。

这通常在通过信令服务器从另一个对等方接收到 offer 或 answer 后调用。请注意,如果在连接已建立的情况下调用 setRemoteDescription(),则意味着正在进行重新协商(可能为了适应不断变化的網絡状况)。

由于描述会在两个对等方就配置达成一致之前进行交换,因此通过调用 setRemoteDescription() 提交的描述不会立即生效。相反,当前的连接配置将保持不变,直到协商完成。届时,商定的配置才会生效。

语法

js
setRemoteDescription(sessionDescription)

// deprecated
setRemoteDescription(sessionDescription, successCallback, errorCallback)

参数

sessionDescription

一个对象,用于指定远程对等方的当前 offer 或 answer。它应包含以下属性:

type

一个字符串,指示会话描述的类型。请参阅 RTCSessionDescription.type

sdp 可选

一个包含描述会话的 SDP 的字符串。如果未提供 sdp,则默认为空字符串。如果 type"rollback",则 sdp 必须为 null 或空字符串。请参阅 RTCSessionDescription.sdp

您也可以传递一个实际的 RTCSessionDescription 实例,但没有区别。因此,RTCSessionDescription 构造函数已弃用。

在旧的代码和文档中,您可能会看到该函数的回调版本。这已弃用,并且强烈不建议使用。您应该将任何现有代码更新为使用 setRemoteDescription() 的基于 Promise 的版本。旧形式的 setRemoteDescription() 的参数如下所述,以帮助更新现有代码。

successCallback 已弃用

一个不接受任何输入参数的 JavaScript Function,当描述成功设置后会被调用。届时,可以通过信令服务器将 offer 发送给远程对等方。

errorCallback 已弃用

一个匹配 RTCPeerConnectionErrorCallback 签名的函数,如果无法设置描述,则会调用该函数。它会收到一个 DOMException 对象,解释请求失败的原因。

此方法的已弃用形式会立即返回,而无需等待实际设置完成:如果成功,将调用 successCallback;如果失败,则调用 errorCallback

返回值

一个 Promise,当连接的 remoteDescription 的值成功更改时,该 Promise 会被 fulfilled;如果更改无法应用(例如,指定的描述与连接上的一个或两个对等方不兼容),则会被 rejected。Promise fulfilled 处理程序不接收任何输入参数。

注意: 更改描述的过程实际上涉及 WebRTC 层处理的中间步骤,以确保在更改不成功时不会丢失连接。有关此过程的更多详细信息,请参阅 WebRTC 连接页面中的 待定和当前描述

异常

以下异常会报告给 setRemoteDescription() 返回的 Promise 的 rejection 处理程序:

InvalidAccessError DOMException

如果描述的内容无效,则返回此异常。

InvalidStateError DOMException

如果 RTCPeerConnection 已关闭,或者其状态与指定的描述的 type 不兼容,则返回此异常。例如,如果 typerollback 且信令状态为 stablehave-local-pranswerhave-remote-pranswer 之一,则会抛出此异常,因为您无法回滚已完全建立或处于连接最终阶段的连接。

OperationError DOMException

如果错误不符合此处指定的错误,则返回此异常。这包括身份验证错误。

RTCError DOMException

RTCSessionDescription.sdp 指定的 SDP 无效时,将返回此异常,并将 errorDetail 设置为 sdp-syntax-error。错误对象的 sdpLineNumber 属性指示了检测到语法错误处的 SDP 行号。

TypeError

如果 sessionDescription 缺少 type 属性,或者根本没有提供描述参数,则返回此异常。

使用已弃用的基于回调的 setRemoteDescription() 版本时,可能会发生以下异常:

InvalidStateError 已弃用

连接的 signalingState"closed",表示连接当前未打开,因此无法进行协商。

InvalidSessionDescriptionError 已弃用

sessionDescription 参数无效。

用法说明

当您调用 setRemoteDescription() 时,ICE 代理会检查以确保 RTCPeerConnection 处于 stablehave-remote-offer signalingState。这些状态表明正在重新协商现有连接,或者将用新的 offer 替换先前通过调用 setRemoteDescription() 指定的 offer。在这两种情况下,我们都处于协商过程的开始阶段,并且 offer 被设置为远程描述。

另一方面,如果我们处于正在进行的协商过程中,并且将 offer 传递给 setRemoteDescription(),ICE 代理会自动开始 ICE 回滚,以将连接恢复到稳定的信令状态,然后,一旦回滚完成,就将远程描述设置为指定的 offer。这会启动一个新的协商会话,以新建立的 offer 作为起点。

在以新建立的 offer 开始新协商后,本地对等方现在成为被叫方,即使它之前是主叫方。这会发生,而不是抛出异常,从而减少了可能发生的潜在错误数量,并通过消除根据本地对等方是主叫方还是被叫方来区分 offer/answer 过程的需要,简化了您在接收 offer 时需要进行的处理。

注意: WebRTC 的早期实现会在 offer 设置在 stablehave-remote-offer 状态之外时抛出异常。

示例

这里我们看到一个处理从远程对等方接收到的 offer 的函数。这段代码改编自文章 信令和视频通话 中的示例和教程;有关更多详细信息和更深入的解释,请参阅该文章。

js
function handleOffer(msg) {
  createMyPeerConnection();

  myPeerConnection
    .setRemoteDescription(msg.description)
    .then(() => navigator.mediaDevices.getUserMedia(mediaConstraints))
    .then((stream) => {
      document.getElementById("local_video").srcObject = stream;
      return myPeerConnection.addStream(stream);
    })
    .then(() => myPeerConnection.createAnswer())
    .then((answer) => myPeerConnection.setLocalDescription(answer))
    .then(() => {
      // Send the answer to the remote peer using the signaling server
    })
    .catch(handleGetUserMediaError);
}

在创建我们的 RTCPeerConnection 并将其保存为 myPeerConnection 后,我们将接收到的 offer 消息 msg 中包含的描述直接传递给 setRemoteDescription(),以告知用户代理的 WebRTC 层调用者使用了什么配置。当我们的 Promise fulfilled 处理程序被调用,表示这已完成,我们就创建一个流,将其添加到连接,然后创建一个 SDP answer 并调用 setLocalDescription() 以在通话的我们这一端将其设置为配置,然后再将该 answer 转发给调用者。

规范

规范
WebRTC:浏览器中的实时通信
# dom-peerconnection-setremotedescription

浏览器兼容性

另见