RTCPeerConnection
=================

**实验性:** **这是一项实验性技术**  
在将其用于生产之前，请仔细检查浏览器兼容性表格。

**`RTCPeerConnection`** 接口代表一个由本地计算机到远端的 WebRTC 连接。该接口提供了创建，保持，监控，关闭连接的方法的实现。

**备注：** `RTCPeerConnection` 和`RTCSessionDescription` 是很多浏览器中使用的名称。强烈建议使用补充库，例如强大并且被广泛支持的Adapter.js，以确保你网站或 Web 应用程序的兼容性。值得注意的是Adapter.js不仅仅提供这些，它还做了一些其他补充以增强 WebRTC 在浏览器中的兼容性。参考：
```

var PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var SessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
var GET_USER_MEDIA = navigator.getUserMedia ? "getUserMedia" :
                     navigator.mozGetUserMedia ? "mozGetUserMedia" :
                     navigator.webkitGetUserMedia ? "webkitGetUserMedia" : "getUserMedia";
var v = document.createElement("video");
var SRC_OBJECT = 'srcObject' in v ? "srcObject" :
                 'mozSrcObject' in v ? "mozSrcObject" :
                 'webkitSrcObject' in v ? "webkitSrcObject" : "srcObject";
```


由于 RTCPeerConnection 实现了 `EventTarget` 接口，故其可以接收处理事件。

### 构造函数

`RTCPeerConnection.RTCPeerConnection()`

构造函数;创建一个新的 RTCPeerConnection 对象。

### 属性

*该接口的属性继承了其父接口，`EventTarget`.*

`RTCPeerConnection.canTrickleIceCandidates` 只读 

`如果远端支持 UDP 打洞或支持通过中继服务器连接，则该属性值为 true。否则，为 false。该属性的值依赖于远端设置且仅在本地的` `RTCPeerConnection.setRemoteDescription()`方法被调用时有效，如果该方法没被调用，则其值为 null.

`RTCPeerConnection.connectionState` 只读 

只读 connectionState 属性通过返回由枚举 RTCPeerConnectionState 指定的字符串值之一来指示对等连接的当前状态。

`RTCPeerConnection.currentLocalDescription` 只读 

只读属性 RTCPeerConnection.currentLocalDescription 返回一个描述连接本地端的 RTCSessionDescription 对象，因为自上次 RTCPeerConnection 完成协商并连接到远程对等体之后，它最近成功协商。还包括可能已经由 ICE 代理生成的任何 ICE 候选者的列表，因为首先被描述的描述所表示的要约或答案。

`RTCPeerConnection.currentRemoteDescription` (en-US) 只读 

只读属性 RTCPeerConnection.currentRemoteDescription 返回一个 RTCSessionDescription 对象，描述连接的远程端，因为最近一次 RTCPeerConnection 完成协商并连接到远程对等体后最近成功协商。还包括可能已经由 ICE 代理生成的任何 ICE 候选者的列表，因为首先被描述的描述所表示的要约或答案。

`RTCPeerConnection.defaultIceServers` 只读 

只读属性 RTCPeerConnection.defaultIceServers 根据 RTCIceServer 字典返回一个对象数组，该字典指示如果在 RTCConfiguration 中没有提供给 RTCPeerConnection 的默认情况下，浏览器将使用 ICE 服务器。然而，浏览器根本不需要提供任何默认的 ICE 服务器。

`RTCPeerConnection.iceConnectionState` 只读 

只读属性 RTCPeerConnection.iceConnectionState 返回与 RTCPeerConnection 关联的 ICE 代理的状态类型为 RTCIceConnectionState 的枚举。

`RTCPeerConnection.iceGatheringState` 只读 

只读属性，返回一个 RTCIceGatheringState 类型的结构体，它描述了连接的 ICE 收集状态

`RTCPeerConnection.idpLoginUrl` 只读 

blah

`RTCPeerConnection.localDescription` (en-US) 只读 

只读属性，返回一个 `RTCSessionDescription` ，它描述了这条连接的本地端的会话控制（用户会话所需的属性以及配置信息）。如果本地的会话控制还没有被设置，它的值就会是 null。

`RTCPeerConnection.peerIdentity` 只读 

只读属性，返回一个 `RTCIdentityAssertion`，它由一组信息构成，包括一个域名（idp）以及一个名称（name），它们代表了这条连接的远端机器的身份识别信息。如果远端机器还没有被设置以及校验，这个属性会返回一个 `null` 值。一旦被设置，它不能被一般方法改变。

`RTCPeerConnection.pendingLocalDescription` (en-US) 只读 

blah

`RTCPeerConnection.pendingRemoteDescription` (en-US) 只读 

blah

`RTCPeerConnection.remoteDescription` 只读 

blah

`RTCPeerConnection.sctp` (en-US) 只读 

blah

`RTCPeerConnection.signalingState` (en-US) 只读 

返回一个 RTC 通信状态的结构体，这个结构体描述了本地连接的通信状态。这个 状态描述了一个定义连接配置的 SDP offer。它包含了下列信息，与`MediaStream` 类型本地相关的对象的描述，媒体流编码方式或 RTP 和 RTCP 协议的选项，以及被 ICE 服务器收集到的 candidates(连接候选者)。当 `RTCPeerConnection.signalingState` (en-US) 的值改变时，对象上的 `signalingstatechange` (en-US) 事件会被触发。

### 基本用法

一个基本的 RTCPeerConnection 使用需要协调本地机器以及远端机器的连接，它可以通过在两台机器间生成 Session Description 的数据交换协议来实现。呼叫方发送一个 offer(请求)，被呼叫方发出一个 answer（应答）来回答请求。双方 - 呼叫方以及被呼叫方，最开始的时候都要建立他们各自的 RTCPeerConnection 对象。
```

var pc = new RTCPeerConnection();
pc.onaddstream = function(obj) {
  var vid = document.createElement("video");
  document.appendChild(vid);
  vid.srcObject = obj.stream;
}

// Helper functions
function endCall() {
  var videos = document.getElementsByTagName("video");
  for (var i = 0; i < videos.length; i++) {
    videos[i].pause();
  }

  pc.close();
}

function error(err) { endCall(); }
```


呼叫初始化

如果你是呼叫方，你需要初始化一个连接
```

// Get a list of friends from a server
// User selects a friend to start a peer connection with
navigator.getUserMedia({video: true}, function(stream) {
  pc.onaddstream({stream: stream});
  // Adding a local stream won't trigger the onaddstream callback
  pc.addStream(stream);

  pc.createOffer(function(offer) {
    pc.setLocalDescription(new RTCSessionDescription(offer), function() {
      // send the offer to a server to be forwarded to the friend you're calling.
    }, error);
  }, error);
})
```


呼叫回答

在另一端，你的朋友会从服务器收到 offer 信息。
```

var offer = getOfferFromFriend();
navigator.getUserMedia({video: true}, function(stream) {
  pc.onaddstream({stream: stream});
  pc.addStream(stream);

  pc.setRemoteDescription(new RTCSessionDescription(offer), function() {
    pc.createAnswer(function(answer) {
      pc.setLocalDescription(new RTCSessionDescription(answer), function() {
        // send the answer to a server to be forwarded back to the caller (you)
      }, error);
    }, error);
  }, error);
})
```


处理应答

同时在呼叫发起方，你会收到这个应答（前面被呼叫方发出的 answer），你需要将它设置为你的远端连接。
```

// pc was set up earlier when we made the original offer
var offer = getResponseFromFriend();
pc.setRemoteDescription(new RTCSessionDescription(offer), function() { }, error);
```

属性
--

*这个接口从它的父元素中继承属性，`EventTarget`.*

`RTCPeerConnection.iceConnectionState` 只读 

返回一个 RTCIceConnectionState 类型的结构体，这个结构体描述了连接的 ICE 连接状态。当这个状态的值改变时，这个对象会触发一个 `iceconnectionstatechange` (en-US) 事件。状态可能存在的值如下：

* "new": ICE 服务器正在收集地址或正在等待远端的 candidates(这两种情况可能同时存在)。
* `"checking"`: ICE 服务器找到了远端的 candidates（连接候选者）,这些 candidates 至少有一个，同时 ICE 服务器在检测这些 candidates，尽管它可能还没有找到连接。此刻，ICE 服务器可能仍在收集 candidates（连接候选者）。
* `"connected"`: ICE 服务器已经找到了一条可用的适合所有组件的连接，但它仍然在测试更多的远端 candidate 以提供更好的连接。同时，ICE 服务器可能仍在收集 candidates。
* `"completed"`: ICE 服务器已经找到了一条可用的连接，并不再测试远端 candidates。
* `"failed"`: ICE 服务器已经检测了所有的远端 candidates，但并没有找到可用的。对一些组件适用的连接可能已经被找到。
* `"disconnected"`: 至少一个组件的活跃度检查失败了，这可能是由糟糕的网络环境造成的一个短期状态，它可以被它自身所修复。
* `"closed"`: ICE 服务器已经关闭，并不再响应请求。

`RTCPeerConnection.iceGatheringState` 只读 

返回一个 iceGatheringState 类型的结构体，它描述了这条连接的 ICE 收集状态。该状态可能取以下的值：

* `"new"`: 对象刚刚被创建，还没有网络化。
* `"gathering"`: ICE 引擎正在为连接收集 candidates(连接候选者)。
* `"complete"`: 引擎已经完成了 candidates 收集。但像添加一个新的接口或者一个新的 turn 服务器这些事件会导致状态回到"gathering"。

`RTCPeerConnection.localDescription` (en-US) 只读 

返回一个 `RTCSessionDescription` ，它描述了这条连接的本地端的会话控制（用户会话所需的属性以及配置信息）。如果本地的会话控制还没有被设置，它的值就会是 null。

`RTCPeerConnection.peerIdentity` 只读 

返回一个`RTCIdentityAssertion，它由一组信息构成，包括一个域名（idp）以及一个名称（name），它们代表了这条连接的远端机器的身份识别信息。如果远端机器还没有被设置以及校验，这个属性会返回一个 null 值。一旦被设置，它不能被一般方法改变`。

`RTCPeerConnection.remoteDescription` 只读 

返回一个 `RTCSessionDescription` 它描述了这条连接的远端机器的会话控制，如果远端机器还未被设置，它的值会是 null。

`RTCPeerConnection.signalingState` (en-US) 只读 

返回一个 RTC 通信状态的结构体，这个结构体描述了本地连接的通信状态。这个 状态描述了一个定义连接配置的 SDP offer。它包含了下列信息，与`MediaStream` 类型本地相关的对象的描述，媒体流编码方式或 RTP 和 RTCP 协议的选项，以及被 ICE 服务器收集到的 candidates(连接候选者)。当`RTCPeerConnection.signalingState` (en-US)的值改变时，对象上的 `signalingstatechange` (en-US) 事件会被触发。它可能取下列的值：

* `"stable"`: 没有 SDP offer/answer 正在被交换，连接仍然处于初始化状态。
* `"have-local-offer"`: 这条连接的本地端机器已经本地应用了一个 SDP offer。
* `"have-remote-offer"`: 这条连接的远端机器已经本地应用了一个 SDP offer。
* `"have-local-pranswer"`: 一个来自远端的 SDP offer 已经被应用，同时一个 SDP pranswer 在本地被应用。
* `"have-remote-pranswer"`：一个本地的 SDP offer 被应用，同时一个 SDP pranswer 在远端被应用。
* `"closed"`: 连接被关闭。

### 事件处理器

`RTCPeerConnection.onaddstream`

是收到 `addstream` 事件时调用的事件处理器。Such an event is 当`MediaStream` 被远端机器添加到这条连接时，该事件会被触发。当调用`RTCPeerConnection.setRemoteDescription()`方法时，这个事件就会被立即触发，它不会等待 SDP 协商的结果。

`RTCPeerConnection.ondatachannel`

是收到 `datachannel` 事件时调用的事件处理器。当一个 `RTCDataChannel` 被添加到连接时，这个事件被触发。

`RTCPeerConnection.onicecandidate`

是收到 `icecandidate` 事件时调用的事件处理器.。当一个 `RTCICECandidate` (en-US) 对象被添加时，这个事件被触发。

`RTCPeerConnection.oniceconnectionstatechange` (en-US)

是收到 `iceconnectionstatechange` 事件时调用的事件处理器。当`iceConnectionState` 改变时，这个事件被触发。

`RTCPeerConnection.onidentityresult`

是收到 `identityresult` 事件时调用的事件处理器。当通过`getIdentityAssertion()` (en-US)生成身份断言，或在生成一个 answer 或一个 offer 的过程中，这个事件被触发。

`RTCPeerConnection.onidpassertionerror`

是收到 `idpassertionerror` 事件时调用的事件处理器。当生成一个身份断言时，如果关联的身份提供者（idP）遇到一个错误，这个事件就会被触发。

`RTCPeerConnection.onidpvalidationerror`

是收到 `idpvalidationerror` 事件时调用的事件处理器。当检查 一个身份断言时，如果关联的身份提供者（idP）遇到一个错误，这个事件就会被触发。

`RTCPeerConnection.onnegotiationneeded` (en-US)

是收到 `negotiationneeded` 事件时调用的事件处理器，浏览器发送该事件以告知在将来某一时刻需要协商。

`RTCPeerConnection.onpeeridentity`

是收到 `peeridentity` 事件时调用的事件处理器，当一条连接的 peer identify 被设置以及校验后，该事件被触发

`RTCPeerConnection.onremovestream` (en-US)

是收到 `removestream` 事件时调用的事件处理器，当一条`MediaStream` 从连接上移除时，该事件被触发。

`RTCPeerConnection.onsignalingstatechange` (en-US)

是收到 `signalingstatechange` 事件时调用的事件处理器，当`signalingState` (en-US)的值发生改变时，该事件被触发。

构造函数
----

`RTCPeerConnection()`

RTCPeerConnection 的初始化函数，通过 new RTCPeerConnection() 初始化一个 RTCPeerConnection 实例。

实例方法
----

`RTCPeerConnection.createOffer()`

生成一个 offer，它是一个带有特定的配置信息寻找远端匹配机器（peer）的请求。这个方法的前两个参数分别是方法调用成功以及失败的回调函数，可选的第三个参数是用户对视频流以及音频流的定制选项（一个对象）。

`RTCPeerConnection.createAnswer()` (en-US)

在协调一条连接中的两端 offer/answers 时，根据从远端发来的 offer 生成一个 answer。这个方法的前两个参数分别是方法调用成功以及失败时的回调函数，可选的第三个参数是生成的 answer 的可供选项。

`RTCPeerConnection.setLocalDescription()` (en-US)

改变与连接相关的本地描述。这个描述定义了连接的属性，例如：连接的编码方式。连接会受到它的改变的影响，而且连接必须能同时支持新的以及旧的描述。这个方法可以接收三个参数，一个`RTCSessionDescription` 对象包含设置信息，还有两个回调函数，它们分别是方法调用成功以及失败的回调函数。

`RTCPeerConnection.setRemoteDescription()`

改变与连接相关的远端描述。这个描述定义了连接的属性，例如：连接的编码方式。连接会受到它的改变的影响，而且连接必须能同时支持新的以及旧的描述。这个方法可以接收三个参数，一个`RTCSessionDescription` 对象包含设置信息，还有两个回调函数，它们分别是方法调用成功以及失败的回调函数。

`RTCPeerConnection.updateIce()`

更新 ICE 服务器时调用的方法。

`RTCPeerConnection.addIceCandidate()`

添加 iceCandidate 时调用的方法。

`RTCPeerConnection.getConfiguration()` (en-US)

获取配置信息时调用的方法。

`RTCPeerConnection.getLocalStreams()` (en-US)

返回连接的本地媒体流数组。这个数组可能是空数组。

`RTCPeerConnection.getRemoteStreams()` (en-US)

返回连接的远端媒体流数组。这个数组可能是空数组。

`RTCPeerConnection.getStreamById()` (en-US)

返回连接中与所给 id 匹配的媒体流 `MediaStream`，如果没有匹配项，返回 null。

`RTCPeerConnection.addStream()` (en-US)

添加一个媒体流 `MediaStream`作为本地音频或视频源。如果本地端与远端协调已经发生了，那么需要一个新的媒体流，这样远端才可以使用它。

`RTCPeerConnection.removeStream()`

将一个作为本地音频或视频源的媒体流 `MediaStream`移除。如果本地端与远端协调已经发生了，那么需要一个新的媒体流，这样远端才可以停止使用它。

`RTCPeerConnection.close()` (en-US)

关闭一个 RTCPeerConnection 实例所调用的方法。

`RTCPeerConnection.createDataChannel()`

在一条连接上建立一个新的`RTCDataChannel`（用于数据发送）。这个方法把一个数据对象作为参数，数据对象中包含必要的配置信息。

`RTCPeerConnection.createDTMFSender()`

创建一个新的与特殊的`MediaStreamTrack`相关的`RTCDTMFSender` (en-US)，可以在连接上发送DTMF (en-US)手机信号。

`RTCPeerConnection.getStats()` (en-US)

生成一个新的`RTCStatsReport`，它包含连接相关的统计信息。

`RTCPeerConnection.setIdentityProvider()` (en-US)

根据所给的三个参数设置身份提供者（IdP)，这三个参数是它的名称，通信所使用的协议（可选），以及一个可选的用户名。只有当一个断言被需要时，这个 IdP 才会被使用。

`RTCPeerConnection.getIdentityAssertion()` (en-US)

初始化身份断言的收集，只有当`signalingState` (en-US)的值不为"closed"时，它才有效。它自动完成，在需求发生前调用它是最好的选择。

规范
--

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # interface-definition |

浏览器兼容性
------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

参见
--

* https://github.com/jesup/nightly-gupshup/blob/master/static/js/chat.js
* WebRTC 入门
* TutorRoom：Node.js HTML 视频捕获、点对点视频和文件共享应用程序（GitHub 上的源码）