如何获取有关WebRTC PeerConnection连接类型的信息?

问题描述 投票:4回答:3

有没有办法以编程方式获取有关WebRTC中使用的连接类型的信息?

例如,在我的应用程序中,我使用本地连接以及STUN和TURN。如果候选者的类型是主机或中继,我可以从ICE候选者收集,并且在服务器上,我可以看到是否通过STUN(连接启动)或TURN(连接期间的稳定流)尝试连接。

到目前为止,我找不到一种方法来访问浏览器中最终使用的连接类型的信息。有候选人,浏览器停止收集,然后有一个工作连接。透过这些事件我找不到任何信息。

我知道Chrome在peerconnection上支持getStats(),这允许我访问chrome:// webrtc-internals中的大部分信息,但我也没有在那里找到这些信息。

有没有办法从JavaScript访问此信息?

非常感谢你。

javascript browser webrtc
3个回答
2
投票

根据the specification(目前在Firefox中实现但不在Chrome中),您确实可以从候选对的统计数据中找出活跃的候选者,这些候选对包括:

dictionary RTCIceCandidatePairStats : RTCStats {
    DOMString                     transportId;
    DOMString                     localCandidateId;
    DOMString                     remoteCandidateId;
    RTCStatsIceCandidatePairState state;
    unsigned long long            priority;
    boolean                       nominated;
    boolean                       writable;
    boolean                       readable;
    unsigned long long            bytesSent;
    unsigned long long            bytesReceived;
    double                        roundTripTime;
    double                        availableOutgoingBitrate;
    double                        availableIncomingBitrate;
};

结合候选人的统计数据:

dictionary RTCIceCandidateAttributes : RTCStats {
    DOMString                ipAddress;
    long                     portNumber;
    DOMString                transport;
    RTCStatsIceCandidateType candidateType;
    long                     priority;
    DOMString                addressSourceUrl;
};

使用peerConnection.getStats()寻找既被提名又成功的冰候选对:

pc.getStats(null))
.then(function(stats) {
  return Object.keys(stats).forEach(function(key) {
    if (stats[key].type == "candidatepair" &&
        stats[key].nominated && stats[key].state == "succeeded") {
      var remote = stats[stats[key].remoteCandidateId];
      console.log("Connected to: " + remote.ipAddress +":"+
                  remote.portNumber +" "+ remote.transport +
                  " "+ remote.candidateType);
    }
  });
})
.catch(function(e) { console.log(e.name); });

这可能会输出如下内容:

Connected to: 192.168.1.2:49190 udp host

你可以测试对LAN range。如果相反它返回如下:

Connected to: 24.57.143.7:61102 udp relayed

然后你有一个TURN连接。

这是一个显示这个的jsfiddle(出于其他原因需要Firefox Developer Edition)。


2
投票

感谢@DavidP和more in-depth answer,我编写了下面的代码来获得ICE Candidates类型。

更新的代码:使用conncectionStats获取ICE候选人

    function getCandidateIds(stats) {
        let ids = {}
        stats.forEach(report => {
            if (report.type == "candidate-pair" && report.nominated && report.state == "succeeded") {
                //console.log("Found IDs")
                ids = {
                    localId: report.localCandidateId,
                    remoteId: report.remoteCandidateId
                }
            }
        });
        return ids
    }

    function getCandidateInfo(stats, candidateId) {
        let info = null
        stats.forEach(report => {
            if (report.id == candidateId) {
                console.log("Found Candidate")
                info = report
            }
        })
        return info
    }

    async function conncectionStats() {
        const stats = await this.pc.getStats(null)
        const candidates = await this.getCandidateIds(stats)
        console.log("candidates: ", candidates)
        if (candidates !== {}) {
            const localCadidate = await this.getCandidateInfo(stats, candidates.localId)
            const remoteCadidate = await this.getCandidateInfo(stats, candidates.remoteId)
            if (localCadidate !== null && remoteCadidate !== null) {
                return [localCadidate, remoteCadidate]
            }
        }
        // we did not find the candidates for whatever reeason
        return [null, null]
    }

读出IP:

  let myAddress = ""
  let peerAddress = ""
  if (localCadidate.hasOwnProperty("ip")){
    myAddress = localCadidate.ip
    peerAddress = remoteCadidate.ip
  } else {
    myAddress = localCadidate.address
    peerAddress = remoteCadidate.address
  }

旧版:

function getConnectionDetails(pc){
  pc.getStats(null)
  .then(function(stats) {
        stats.forEach(report => {
          if (report.type == "candidate-pair" 
              && report.nominated 
              && report.state == "succeeded")
          {
            console.log( "Local ICE:", report.localCandidateId)
            console.log( "Remote ICE:",report.remoteCandidateId)
            getCandidates(pc, report.localCandidateId, report.remoteCandidateId)
          }
      });
  })
  .catch(function(e) { console.log(e.name); });
};

function getCandidates(pc, localId, remoteId){
  //console.log("looking for candidates")
  pc.getStats(null)
  .then(function(stats) {
        stats.forEach(report => {
          if (report.id == localId) {
              console.log("Local: Type:", report.candidateType," IP:", report.ip)
          } else if (report.id == remoteId){
              console.log("Remote: Type:", report.candidateType," IP:", report.ip)
          }
      })
  })
  .catch(function(e) { console.log(e.name); });
}

根据应提取的信息,您可能不需要两个候选人。


1
投票

jib从2015年3月开始的答案非常有用,但在2019年3月不适用于Firefox v65或Chrome v72(在Windows上)。需要两个更新:

1)“stats”值现在在两个浏览器中都有RTCStatsReport类型,它是一个没有键的可迭代对象。因此,使用forEach(report => {...})迭代它,“report”将是一个对象,其中的键就像jib为“stats”显示的那样。

2)“candidatepair”不是report.type的有效值,而是“候选对”。

© www.soinside.com 2019 - 2024. All rights reserved.