WebRTC - 如何设置始终使用TURN服务器?

4
在标准规范中,它说您可以将ENUM值设置为“relay”:http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceServer 但是,如何使用以下Javascript将枚举设置为“relay”? if (tmp.indexOf("typ relay ") >= 0) {在我的测试中从未发生。我如何强制它转换为枚举“relay”?
还是这是个BUG?https://code.google.com/p/webrtc/issues/detail?id=1179 有什么想法。
function createPeerConnection() {
  try {
    // Create an RTCPeerConnection via the polyfill (adapter.js).
    pc = new RTCPeerConnection(pcConfig, pcConstraints);
    pc.onicecandidate = onIceCandidate;
    console.log('Created RTCPeerConnnection with:\n' +
                '  config: \'' + JSON.stringify(pcConfig) + '\';\n' +
                '  constraints: \'' + JSON.stringify(pcConstraints) + '\'.');
  } catch (e) {
    console.log('Failed to create PeerConnection, exception: ' + e.message);
    alert('Cannot create RTCPeerConnection object; \
          WebRTC is not supported by this browser.');
      return;
  }
  pc.onaddstream = onRemoteStreamAdded;
  pc.onremovestream = onRemoteStreamRemoved;
  pc.onsignalingstatechange = onSignalingStateChanged;
  pc.oniceconnectionstatechange = onIceConnectionStateChanged;
}

function onIceCandidate(event) {
  if (event.candidate) {
    var tmp = event.candidate.candidate;
    if (tmp.indexOf("typ relay ") >= 0) {
      /////////////////////////////////////////// NEVER happens
      sendMessage({type: 'candidate',
                   label: event.candidate.sdpMLineIndex,
                   id: event.candidate.sdpMid,        
                   candidate: tmp}); 
      noteIceCandidate("Local", iceCandidateType(tmp));   

    }    
  } else {
    console.log('End of candidates.');
  }
}
3个回答

7

有一个名为WebRTC Network Limiter的Chrome扩展程序,可以通过更改Chrome的隐私设置来配置WebRTC的网络流量路由。您可以强制流量通过TURN而无需进行任何SDP操纵。


编辑1

提供这个扩展的目的是为了担心安全问题的用户。您可以查看this关于WebRTC安全性的优秀文章。与此扩展程序所做的相同,也可以在Firefox中通过更改标志media.peerconnection.ice.relay_only来完成。这可以在about:config中找到。我不知道另外两个,但我敢打赌它们也有类似的东西。

另一方面,如果您正在分发应用程序并希望所有客户端都通过TURN进行通信,则无法访问其浏览器,并且不能指望他们更改这些标志或安装任何扩展程序。在这种情况下,您将不得不篡改自己的SDP。您可以使用此代码。

function onIceCandidate(event) {
  if (event.candidate) {
    var type = event.candidate.candidate.split(" ")[7];
    if (type != "relay") {
      trace("ICE  -  Created " + type + " candidate ignored: TURN only mode.");
      return;
    } else {
      sendCandidateMessage(candidate);
      trace("ICE  - Sending " + type + " candidate.");
    }
  } else {
    trace("ICE  - End of candidate generation.");
  }
}

那段代码来自讨论WebRTC列表。
如果你从未收到这些候选者,很可能是因为你的TURN服务器配置不正确。你可以在这个页面检查你的TURN服务器。不要忘记删除该演示中配置的现有STUN服务器。

编辑2

更简单的方法是在WebRtcPeer配置中设置iceTransportPolicy: "relay"来强制使用TURN:

var options = {
    localVideo: videoInput, //if you want to see what you are sharing
    onicecandidate: onIceCandidate,
    mediaConstraints: constraints,
    sendSource: 'screen',
    iceTransportPolicy: 'relay',
    iceServers: [{ urls: 'turn:XX.XX.XX.XX', username:'user', credential:'pass' }]
}

webRtcPeerScreencast = kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv(options, function(error) {
    if (error) return onError(error) //use whatever you use for handling errors

    this.generateOffer(onOffer)
});

我能在 OPERA、FIREFOX 和 NODE-WebKit 中使用这个扩展吗?如果不能,那么仅为 Google 制作的扩展有何意义呢? - user285594
@YumYumYum 很抱歉,该扩展程序只适用于Chrome浏览器。FF有另一种方法来实现这个功能,所以我已经扩展了答案,并在其中包含了更多信息。 - igracia
@YumYumYum 还添加了另一种方法来完成这个任务。 - igracia
EDIT 2 已经完美运行! - user2677034

6
这对我有用:
iceServers = [
     { "url": "turn:111.111.111.111:1234?transport=tcp",
       "username": "xxxx",
       "credential": "xxxxx"
     }
   ]

optionsForWebRtc = {
    remoteVideo : localVideoElement,
    mediaConstraints : videoParams,
    onicecandidate : onLocalIceCandidate,
    configuration: {
        iceServers: iceServers,
        iceTransportPolicy: 'relay'
    }
}

1
请分享完整代码。实际上我已经在AWS中部署了自己的转向服务器,但不知道如何连接。 - Satanand Tiwari

2
要强制使用TURN服务器,您需要拦截浏览器找到的候选项。就像您正在做的那样。但如果在您的测试中从未出现过这种情况,则可能存在TURN服务器的问题。如果您有一个可用的TURN服务器,您将获得具有“typ relay”的候选项。请记住,您需要配置带有身份验证的TURN服务器。这是强制性的,仅当请求经过身份验证时,浏览器才会使用“relay”候选项。您的PeerConnection的iceServers配置必须为TURN服务器定义凭据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接