开发手册 欢迎您!
软件开发者资料库

WebRTC - RTCPeerConnection API

WebRTC RTCPeerConnection API - 从概述,架构,环境,MediaStream API,RTCPeerConnection API,RTCDataChannel API,发送消息,信令,浏览器支持,移动支持,视频演示,语音演示,文本演示,安全性开始学习WebRTC。

RTCPeerConnection API是每个浏览器之间对等连接的核心.要创建RTCPeerConnection对象,只需编写

  var pc = RTCPeerConnection(config);

其中 config 参数至少包含key,iceServers.它是一个URL对象数组,包含有关STUN和TURN服务器的信息,在查找ICE候选项时使用.您可以在代码中找到可用的公共STUN服务器列表.google.com

根据您是调用者还是被调用者,RTCPeerConnection对象在连接的每一侧以稍微不同的方式使用.

以下是用户流量和减号的示例;

  • 注册 onicecandidate 处理程序.它会在收到任何ICE候选人时将其发送给另一个同行.

  • 注册 onaddstream 处理程序.它处理从远程对等方收到视频流后的视频流.

  • 注册消息处理程序.您的信令服务器还应具有从其他对等方接收的消息的处理程序.如果消息包含 RTCSessionDescription 对象,则应使用 setRemoteDescription()方法将其添加到 RTCPeerConnection 对象.如果消息包含 RTCIceCandidate 对象,则应使用 addIceCandidate()方法将其添加到 RTCPeerConnection 对象.

  • 利用 getUserMedia()设置本地媒体流,并使用 addStream将其添加到 RTCPeerConnection 对象()方法.

  • 开始提供/回答谈判过程.这是调用者的流量与被调用者的流量不同的唯一步骤.调用者使用 createOffer()方法开始协商,并注册接收 RTCSessionDescription 对象的回调.然后,此回调应使用 setLocalDescription()将此 RTCSessionDescription 对象添加到 RTCPeerConnection 对象.最后,调用者应使用信令服务器将此 RTCSessionDescription 发送到远程对等方.另一方面,被调用者注册相同的回调,但是在 createAnswer()方法中.请注意,只有在从调用者收到商品后才会启动被调用者流程.

RTCPeerConnection API

属性

  • RTCPeerConnection.iceConnectionState(只读) : 返回描述连接状态的RTCIceConnectionState枚举.此值更改时会触发iceconnectionstatechange事件.可能的值 :

    • new :  ICE代理正在等待远程候选人或收集地址

    • 检查 :  ICE代理有远程候选人,但尚未找到连接

    • 已连接 :  ICE代理已找到可用的连接,但仍在检查更远的候选者以获得更好的连接.

    • 已完成 :  ICE代理已找到可用的连接并停止测试远程候选人.

    • 失败 :  ICE代理检查了所有远程候选人,但没有找到至少一个组件的匹配.

    • 已断开连接 : 至少有一个组件不再存在.

    • 已关闭 :  ICE代理已关闭.

  • RTCPeerConnection.iceGatheringState(只读) : 返回描述连接的ICE收集状态的RTCIceGatheringState枚举 :

    • new : 该对象刚刚创建.

    • 收集 :  ICE代理正在收集候选人

    • 完成 ICE代理已完成聚会.

  • RTCPeerConnection.localDescription(只读) : 返回描述本地会话的RTCSessionDescription.如果尚未设置,则它可以为null.

  • RTCPeerConnection.peerIdentity(只读) : 返回RTCIdentityAssertion.它由一个idp(域名)和一个代表远程对等体身份的名称组成.

  • RTCPeerConnection.remoteDescription(只读) : 返回描述远程会话的RTCSessionDescription.如果尚未设置,则它可以为null.

  • RTCPeerConnection.signalingState(只读) : 返回描述本地连接的信令状态的RTCSignalingState枚举.此状态描述了SDP提供.此值更改时会触发signalingstatechange事件.可能的值 :

    • 稳定 : 初始状态.正在进行SDP优惠/回答交换.

    • have-local-offer : 连接的本地端已在本地应用SDP优惠.

    • have-remote-offer : 连接的远程端已在本地应用了SDP优惠.

    • have-local-pranswer : 已经应用了远程SDP优惠,并在当地应用了SDP pranswer.

    • have-remote-pranswer : 已应用本地SDP,并远程应用SDP pranswer.

    • 已关闭 : 连接已关闭.

事件处理程序

S.No.事件处理程序&说明
1

RTCPeerConnection.onaddstream

触发addstream事件时会调用此处理程序.当远程对等方将MediaStream添加到此连接时,将发送此事件.

2

RTCPeerConnection.ondatachannel

触发datachannel事件时会调用此处理程序.将RTCDataChannel添加到此连接时会发送此事件.

3

RTCPeerConnection.onicecandidate

在触发icecandidate事件时调用此处理程序.将RTCIceCandidate对象添加到脚本时发送此事件.

4

RTCPeerConnection.oniceconnectionstatechange

在触发iceconnectionstatechange事件时调用此处理程序.当iceConnectionState的值发生变化时,将发送此事件.

5

RTCPeerConnection.onidentityresult

触发identityresult事件时会调用此处理程序.在创建商品或通过getIdentityAssertion()的回答期间生成标识声明时发送此事件.

6

RTCPeerConnection.onidpassertionerror

当idpassertionerror事件发生时,将调用此处理程序被解雇.当IdP(Identitry Provider)在生成标识声明时发现错误时发送此事件.

7

RTCPeerConnection.onidpvalidation

触发idpvalidationerror事件时会调用此处理程序.当IdP(Identitry Provider)在验证身份声明时发现错误时发送此事件.

8

RTCPeerConnection.onnegotiationneeded

触发negotiationneeded事件时调用此处理程序.此事件由浏览器发送,以告知将来某个时候需要协商.

9

RTCPeerConnection.onpeeridentity

触发peeridentity事件时会调用此处理程序.在此连接上设置并验证对等身份后发送此事件.

10

RTCPeerConnection.onremovestream

触发signalingstatechange事件时会调用此处理程序.如果signalingState的值发生变化,则会发送此事件.

11

RTCPeerConnection.onsignalingstatechange

触发removestream事件时会调用此处理程序.从此连接中删除MediaStream时会发送此事件.

方法

S.No.Methods&说明
1

RTCPeerConnection()

返回一个新的RTCPeerConnection对象.

2

RTCPeerConnection.createOffer()

创建要约(请求)以查找远程对等方.此方法的两个第一个参数是成功和错误回调.可选的第三个参数是选项,如启用音频或视频流.

3

RTCPeerConnection.createAnswer()

在提供/应答协商过程中创建远程对等方收到的要约的答案.此方法的两个第一个参数是成功和错误回调.可选的第三个参数是要创建的答案的选项.

4

RTCPeerConnection.setLocalDescription()

更改本地连接描述.该描述定义了连接的属性.连接必须能够支持旧描述和新描述.该方法需要三个参数,RTCSessionDescription对象,如果描述更改成功则回调,如果描述更改失败则回调.

5

RTCPeerConnection.setRemoteDescription()

更改远程连接描述.该描述定义了连接的属性.连接必须能够支持旧描述和新描述.该方法需要三个参数,RTCSessionDescription对象,如果描述更改成功则回调,如果描述更改失败则回调.

6

RTCPeerConnection.updateIce()

更新ICE代理ping过程远程候选人和当地候选人.

7

RTCPeerConnection.addIceCandidate()

为ICE代理提供远程候选.

8

RTCPeerConnection.getConfiguration()

返回RTCConfiguration对象.它表示RTCPeerConnection对象的配置.

9

RTCPeerConnection.getLocalStreams()

返回本地MediaStream连接的数组.

10

RTCPeerConnection.getRemoteStreams()

返回一个远程MediaStream连接数组.

11

RTCPeerConnection.getStreamById()

按给定ID返回本地或远程MediaStream.

12

RTCPeerConnection.addStream()

将MediaStream添加为本地视频或音频源.

13

RTCPeerConnection.removeStream()

将MediaStream移除为本地视频或音频源.

14

RTCPeerConnection.close ()

Clo建立连接.

15

RTCPeerConnection.createDataChannel()

创建一个新的RTCDataChannel.

16

RTCPeerConnection.createDTMFSender()

创建一个新的RTCDTMFSender,与特定MediaStreamTrack关联.允许通过连接发送DTMF(双音多频)电话信号.

17

RTCPeerConnection.getStats()

创建一个新的RTCStatsReport,其中包含有关连接的统计信息.

18

RTCPeerConnection.setIdentityProvider()

设置IdP.采用三个参数 - 名称,用于通信的协议和可选的用户名.

19

RTCPeerConnection.getIdentityAssertion()

收集身份断言.预计不会在应用程序中处理此方法.所以你可以明确地称之为预期需要.

建立连接

现在让我们创建一个示例应用程序.首先,通过"节点服务器"运行我们在"信令服务器"教程中创建的信令服务器.

页面上将有两个文本输入,一个用于登录,一个用于a我们想要连接的用户名.创建 index.html 文件并添加以下代码 :

                         
                    Login       
       
                   Establish connection       
          

您可以看到我们已经为登录添加了文本输入,登录按钮,其他对等用户名的文本输入以及连接 - 给他按钮.现在创建一个 client.js 文件并添加以下代码 :

var connection = new WebSocket('ws://localhost:9090'); var name = "";  var loginInput = document.querySelector('#loginInput'); var loginBtn = document.querySelector('#loginBtn'); var otherUsernameInput = document.querySelector('#otherUsernameInput'); var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn'); var connectedUser, myConnection;  //when a user clicks the login button loginBtn.addEventListener("click", function(event){    name = loginInput.value;    if(name.length > 0){       send({          type: "login",          name: name       });    } });  //handle messages from the server connection.onmessage = function (message) {    console.log("Got message", message.data);   var data = JSON.parse(message.data);    switch(data.type) {       case "login":          onLogin(data.success);          break;       case "offer":          onOffer(data.offer, data.name);          break;       case "answer":          onAnswer(data.answer);          break;       case "candidate":          onCandidate(data.candidate);          break;       default:          break;    } };  //when a user logs in function onLogin(success) {    if (success === false) {       alert("oops...try a different username");    } else {       //creating our RTCPeerConnection object       var configuration = {          "iceServers": [{ "url": "stun:stun.1.google.com:19302" }]       };       myConnection = new webkitRTCPeerConnection(configuration);       console.log("RTCPeerConnection object was created");       console.log(myConnection);         //setup ice handling      //when the browser finds an ice candidate we send it to another peer       myConnection.onicecandidate = function (event) {          if (event.candidate) {             send({                type: "candidate",                candidate: event.candidate             });          }       };    } };  connection.onopen = function () {    console.log("Connected"); };  connection.onerror = function (err) {    console.log("Got error", err); };  // Alias for sending messages in JSON format function send(message) {    if (connectedUser) {       message.name = connectedUser;    }    connection.send(JSON.stringify(message)); };

您可以看到我们建立了与信令服务器的套接字连接.当用户单击登录按钮时,应用程序将其用户名发送到服务器.如果登录成功,应用程序将创建RTCPeerConnection对象并设置onicecandidate处理程序,该处理程序将所有找到的icecandidates发送给另一个对等方.现在打开页面并尝试登录.您应该看到以下控制台输出 :

Establishing a Connection

下一步是为其他对等方创建要约.将以下代码添加到 client.js 文件 :

//setup a peer connection with another user connectToOtherUsernameBtn.addEventListener("click", function () {     var otherUsername = otherUsernameInput.value;    connectedUser = otherUsername;   if (otherUsername.length > 0) {       //make an offer       myConnection.createOffer(function (offer) {          console.log();          send({             type: "offer",             offer: offer          });         myConnection.setLocalDescription(offer);       }, function (error) {          alert("An error has occurred.");       });    } });  //when somebody wants to call us function onOffer(offer, name) {    connectedUser = name;    myConnection.setRemoteDescription(new RTCSessionDescription(offer));    myConnection.createAnswer(function (answer) {       myConnection.setLocalDescription(answer);       send({          type: "answer",          answer: answer       });    }, function (error) {       alert("oops...error");    }); }  //when another user answers to our offer function onAnswer(answer) {    myConnection.setRemoteDescription(new RTCSessionDescription(answer)); }  //when we got ice candidate from another user function onCandidate(candidate) {    myConnection.addIceCandidate(new RTCIceCandidate(candidate)); }

您可以看到,当用户点击"建立连接"按钮时,应用程序会向另一个对等方提供SDP优惠.我们还设置了 onAnswer onCandidate 处理程序.重新加载您的页面,在两个选项卡中打开它,使用两个用户登录并尝试在它们之间建立连接.您应该看到以下控制台输出 :

控制台输出

现在建立对等连接.在下一个教程中,我们将添加视频和音频流以及文本聊天支持.