2 回答

TA貢獻1765條經驗 獲得超5個贊
在兩個瀏覽器窗口中打開它,然后點擊其中一個窗口中的按鈕。這是代碼:Connect
const pc = new RTCPeerConnection();
call.onclick = async () => {
const stream = await navigator.mediaDevices.getUserMedia({video:true,audio:true})
video.srcObject = stream;
for (const track of stream.getTracks()) {
pc.addTrack(track, stream);
}
};
pc.ontrack = ({streams}) => video.srcObject = streams[0];
pc.oniceconnectionstatechange = () => console.log(pc.iceConnectionState);
pc.onicecandidate = ({candidate}) => sc.send({candidate});
pc.onnegotiationneeded = async () => {
await pc.setLocalDescription(await pc.createOffer());
sc.send({sdp: pc.localDescription});
}
const sc = new localSocket(); // localStorage signaling hack
sc.onmessage = async ({data: {sdp, candidate}}) => {
if (sdp) {
await pc.setRemoteDescription(sdp);
if (sdp.type == "offer") {
await pc.setLocalDescription(await pc.createAnswer());
sc.send({sdp: pc.localDescription});
}
} else if (candidate) await pc.addIceCandidate(candidate);
}
這是A和B的相同來源,用您喜歡的信令通道(例如websocket)替換黑客攻擊。localSocket
不要緩存ICE候選者,因為這違背了涓流ICE的目的。它可能在本地看起來很快,但在實際網絡中ICE可能需要時間。
事實上,如果您延遲發送報價/答案,直到收集了所有本地候選人,則發送候選人是沒有意義的,因為候選人已經嵌入到提議/答案()中。pc.localDescription

TA貢獻1876條經驗 獲得超7個贊
最后!幾周后,我已經弄清楚了這個問題,這個問題在我的問題中包含的代碼中并不明顯,但對于遇到類似問題的人來說,它可能仍然有用。
我以為在活動結束后,冰上收集正在完成,并且提供了報價/答案。onnegotiationneeded
由于這個不正確的假設,我在這個階段與冰候選人一起發出報價/答案的信號,但是非常頻繁地(根據我的經驗,總是在iOS Safari中)此時尚未創建報價/答案。
我通過創建兩個承諾來解決這個問題:a)完成冰候選收集,以及b)創建報價/答案。我使用了兩個承諾,當它們都完成時,我通過信令服務器同時發送了冰候選者和提供/答案。Promise.all
這是可行的,但是當然在未來,我應該通過發送零碎的東西來“涓涓細流”這些信息,而不是等待一切完全完成。但是我將來會擔心這一點,因為目前我正在使用HTTP請求,而且這太麻煩了。
編輯:我的連接仍然總是卡住,所以我創建了一個新問題。但是,如果沒有本地連接,則現在100%完全可靠:)iceServers
iceServers
添加回答
舉報