目前,我有一个使用 WebRTC 并用部署在 AWS EC2 实例上的 Reactjs 编写的视频聊天 Web 应用程序。视频聊天与本地网络或同一 Internet 网络上的两台不同计算机上的两个用户一起工作,我们可以轻松地交谈和看到对方。
但是,当我尝试与其他网络上的另一个用户进行视频聊天时,视频聊天停止工作,并且我在 Chrome 浏览器控制台中收到如下错误消息:
Uncaught (in promise) DOMException: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Error processing ICE candidate
另一个用户得到:
ICE failed, add a STUN server and see about:webrtc for more details
我相信问题出在 TURN 服务器上,但是我已经在 AWS EC2 实例上使用 COTURN ( https://github.com/coturn/coturn )设置了 TURN 服务器,当我在https上对其进行测试时它似乎可以工作: //webrtc.github.io/samples/src/content/peerconnection/trickle-ice/当我尝试查看中继时使用相同的凭据。
我使用此 stackoverflow 帖子中的说明部署了 TURN 服务器: How to create stun turn server instance using AWS EC2
我还允许对 AWS 安全组上的大量端口进行 UDP 和 TCP 的入站端口访问。
一些相关代码,这个处理我从 WebRTC 信令服务器返回的响应:
/**
* Parse a broadcast message and reply back with
* the appropriate details
*/
receiveBroadcast(packetObject) {
try {
var payload = JSON.parse(packetObject.Payload)
} catch (err) {
var payload = packetObject.Payload
}
if (payload.Type == 'Ice Offer') {
// Set remote descriptions and construct an ICE answer
var icePacket = new this.rtcSessionDescription({
type: payload.IcePacket.type,
sdp: payload.IcePacket.sdp,
})
this.peerConnection.setRemoteDescription(icePacket, function () {
this.peerConnection.createAnswer(this.onCreateAnswerSuccess.bind(this), this.onCreateSessionDescriptionError)
}.bind(this), this.onSetSessionDescriptionError)
} else if (payload.Type == 'Ice Answer') {
// Set the remote description
var icePacket = new this.rtcSessionDescription({
type: payload.IcePacket.type,
sdp: payload.IcePacket.sdp,
})
this.peerConnection.setRemoteDescription(icePacket, function () {
this.onSetRemoteSuccess()
}.bind(this), this.onSetSessionDescriptionError)
} else if (payload.Type == 'Ice Candidate') {
console.log('ICE payload :')
console.log(payload)
// Add the candidate to the list of ICE candidates
var candidate = new this.rtcIceCandidate({
sdpMLineIndex: payload.sdpMLineIndex,
sdpMid: payload.sdpMid,
candidate: payload.candidate,
})
this.peerConnection.addIceCandidate(candidate)
}
}
它主要是最后一行不起作用。
我设置了 console.logs 以查看该过程的样子:
Local stream set
bundle.js:1 Video Set
bundle.js:1 setRemoteDescription complete
bundle.js:1 ICE payload :
bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "candidate:0 1 UDP 2122252543 xxx.xxx.x.xx 57253 typ host", sdpMid: "0"}
bundle.js:1 ICE payload :
bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "candidate:1 1 UDP 2122187007 xx.xxx.x.xx 53622 typ host", sdpMid: "0"}
bundle.js:1 ICE payload :
bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "candidate:2 1 TCP 2105524479 xxx.xxx.x.xx 9 typ host tcptype active", sdpMid: "0"}
bundle.js:1 ICE payload :
bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "candidate:3 1 TCP 2105458943 xx.xxx.x.xx 9 typ host tcptype active", sdpMid: "0"}
bundle.js:1 ICE payload :
bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "", sdpMid: "0"}