繁体   English   中英

为什么 WebRTC 只有在第二次报价后才建立连接?

[英]Why does WebRTC set up a connection only after second offer?

我想设置一个 WebRTC 数据通道并发送一些文本。 因此,我创建了一个带有“oniceccandidate”和“ondatachannel”处理程序的 RTCPeerConnection object。 (我将 RTCPeerConnection 的“配置”保留为空,因为连接仅在本地主机之间。)

var configuration = {}; 
myConnection = new RTCPeerConnection(configuration);
  
myConnection.onicecandidate = function (event) {
    if (event.candidate) { 
        send({ 
            type: "candidate", 
            candidate: event.candidate 
        }); 
    } 
};

myConnection.ondatachannel = function (event) {
    dataChannel = event.channel;
    dataChannel.onerror = function (error) { 
        console.log("Error:", error); 
    };
                
    dataChannel.onmessage = function (event) { 
        console.log("RTC message:", event.data); 
    };  
};

然后我从 A 向 B 发送报价。

offer = await myConnection.createOffer();
await myConnection.setLocalDescription(offer);
send({type: "offer", offer: offer});

接收器 B 然后发送一个答案。

async function onOffer(offer, name) { 
    myConnection.setRemoteDescription(new RTCSessionDescription(offer));

    answer = await myConnection.createAnswer();
    await myConnection.setLocalDescription(answer);
    send({type: "answer", answer: answer});
}

其中A设置为远程描述并打开数据通道。

function onAnswer(answer) { 
    myConnection.setRemoteDescription(new RTCSessionDescription(answer));
    openDataChannel();
}

function openDataChannel() { 
    var dataChannelOptions = { 
        reliable:true 
    }; 
    
    dataChannel = myConnection.createDataChannel("myDataChannel", dataChannelOptions);
        
    dataChannel.onerror = function (error) { 
        console.log("Error:", error); 
    };
        
    dataChannel.onmessage = function (event) { 
        console.log("RTC message:", event.data); 
    };  
}

还有一个 function 处理双方收到的候选人。

function onCandidate(candidate) { 
    myConnection.addIceCandidate(new RTCIceCandidate(candidate));
}

A 发送第一个 offer 后,它收到了一个答复,但 RTCPeerConnection 的“iceGatheringState”和“iceConnectionState”保持“new”。 不会触发“onicecandidate”事件。 在 A 再次调用 createOffer() 之后,报价看起来“更大”(包含更多值)。 将第二个提议设置为本地描述后,双方都会触发“onicecandicate”事件。 但数据通道只有在 A 向 B 发送第二个 offer 后才建立。

我知道是同一个问题,但答案似乎不合适,因为我有一个“oniceccandidate”处理程序。 我也读到了涓流冰,但仍然不知道问题是什么。

在协商之前,您必须至少调用一次myConnection.createDataChannel ,以使连接协商数据通道的使用。 默认情况下不包括它们。

在那之前没有媒体,也没有数据通道,没有什么可协商的。 这使您的第一次协商变得多余,无操作,这就是 state 永远不会离开"new"的原因。

完成此操作后,无需再次执行此操作,因为所有后续数据通道都通过同一个 sctp 传输多路复用。

要仅在需要时进行协商,请考虑设置:

pc.onnegotiationneeded = async () => {
  try {
    await pc.setLocalDescription(await pc.createOffer());
    send({type: "offer", offer: pc.localDescription});
  } catch (e) {
    console.error(e);
  }
};

然后,当您第一次调用pc.createDataChannel时(但不是随后的时间),将自动触发协商。

但是,如果您在两端都这样做,或者使用完美的谈判模式,请注意眩光。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM