WebRTC: 在错误的状态下调用:STATE_SENTOFFER

3
我正在遵循这篇教程,制作一个简单的WebRTC示例。但是远程视频在任何浏览器中都不会出现,并且Chrome没有显示错误信息:

Uncaught (in promise) DOMException: Error processing ICE candidate

我在not setRemoteDescription方法中进行了日志记录:
peerConn.setRemoteDescription(new RTCSessionDescription(signal.sdp), function(){
       alert('success')
    }, function(e){ console.log(e); alert(e)});

然后我遇到了以下错误:

操作错误:无法设置远程offer的sdp:在错误的状态下调用:STATE_SENTOFFER

在相关教程中,作者声称他能够做到一切正确,问题应该出在我的身上。有没有人经历过这种情况?

(对于我的英语,我很抱歉)


编辑:(包括代码)

我仍然是一个业余爱好者,引用开头的教程链接是我找到的最干净的开始入门的方式。我会放置我认为重要的源代码:

后端 - server.js

/** successful connection */
wss.on('connection', function (client) {
  console.log("A new WebSocket client was connected.");
  /** incomming message */
  client.on('message', function (message) {
    /** broadcast message to all clients */
    wss.broadcast(message, client);
  });
});
// broadcasting the message to all WebSocket clients.
wss.broadcast = function (data, exclude) {
  var i = 0, n = this.clients ? this.clients.length : 0, client = null;
  if (n < 1) return;
  console.log("Broadcasting message to all " + n + " WebSocket clients.");
  for (; i < n; i++) {
    client = this.clients[i];
    // don't send the message to the sender...
    if (client === exclude) continue;
    if (client.readyState === client.OPEN) client.send(data);
    else console.error('Error: the client state is ' + client.readyState);
  }
};

前端 - webrtc.js

wsc.onmessage = function (evt) {
  var signal = null;
  if (!peerConn) answerCall();
  signal = JSON.parse(evt.data);
  if (signal.sdp) {
    console.log("Received SDP from remote peer.");
    peerConn.setRemoteDescription(new RTCSessionDescription(signal.sdp), 
      function(){}, 
      function(e){ console.log(e); 
    });
  }
  else if (signal.candidate) {
    console.log("Received ICECandidate from remote peer.");
    peerConn.addIceCandidate(new RTCIceCandidate(signal.candidate));
  } else if ( signal.closeConnection){
    console.log("Received 'close call' signal from remote peer.");
    endCall();
  }
};

所有字体: 代码取自此 Github 存储库。

answerCall() 函数是用来回应呼叫的。请注意,在调用 createAnswer() 之前,必须先调用 setRemoteDescription(offer)。因为 offer 是回应的基础。 - jib
1个回答

4

没有代码很难回答,但至少有两个问题,根据以下两个错误进行判断:

Uncaught (in promise) DOMException: 处理 ICE 候选项时出错

这是由于 peerConn.addIceCandidate(candidate) 中的候选项输入存在问题,表明它不正确或已经被破坏。你需要从另一端的 peerConn.onicecandidate 通过信令通道发送候选项。如果需要更多帮助,请展示代码。

它是“未捕获”的,因为它返回一个promise,并且你忽略了 .catch

peerConn.addIceCandidate(candidate).catch(e => console.log(e));

操作错误:无法设置远程的SDP(Session Description Protocol): 在错误的状态 STATE_SENTOFFER 中被调用。

这意味着双方同时尝试发送一个Offer,这是对称且错误的。

Offer/Answer交换过程本质上是不对称的。一方必须首先发出一个Offer,另一方接收该Offer,使用SetRemote协议创建一个Answer并将其发送回第一方。这种过程就像一个状态机,任何一个步骤出错都会导致类似于此类的错误。


添加到catch语句中:“addIceCandidate:OperationError:处理ICE候选项时出错”。附注:主题中包括源代码。 - luisdemarchi
我发现使用本地主机是可以的,但当我尝试连接网络时出现错误。同时确保SSL端口已释放。 - luisdemarchi
@LuísDeMarchi 这表明你的 ICE 候选项出了问题。尝试在发送方和接收方记录它们到控制台。 - jib
非常感谢,我之前使用了原始API和两个WebRTC库,出现了第二个错误。我将第二个对等方的邀请放到了“onAnswer”中,问题得到了解决。 - jcubic

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