亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

WebRTC卡在連接狀態

WebRTC卡在連接狀態

人到中年有點甜 2022-09-02 16:06:20
我已經成功地傳達了從A到B的WebRTC連接的報價,答案和冰候選人。此時,連接卡在狀態。啟動器(A)似乎在一段時間后超時或什么,并切換到狀態,而它的遠程(B)則永久停留在狀態。"connecting""failed""connecting"任何幫助將不勝感激。創建對等節點(A 和 B):let peer = new RTCPeerConnection({    iceServers: [        {            urls: [                "stun:stun1.l.google.com:19302",                "stun:stun2.l.google.com:19302",            ],        },        {            urls: [                "stun:global.stun.twilio.com:3478?transport=udp",            ],        },    ],    iceCandidatePoolSize: 10,});創建報價 (A):peer.onnegotiationneeded = async () => {    offer = await peer.createOffer();    await peer.setLocalDescription(offer);};收集冰候選者(A):peer.onicecandidate = (evt) => {    if (evt.candidate) {        iceCandidates.push(evt.candidate);    } else {        // send offer and iceCandidates to B through signaling server        // this part is working perfectly    }};創建答案并填充候選冰 (B):await peer.setRemoteDescription(offer);let answer = await this._peer.createAnswer();await peer.setLocalDescription(answer);// send answer back to A through signaling serverfor (let candidate of sigData.iceCandidates) {    await peer.addIceCandidate(candidate);}從 B 到信令服務器 (A) 的應答:await peer.setRemoteDescription(answer);檢測連接狀態更改(A 和 B):peer.onconnectionstatechange = () => {    console.log("state changed")    console.log(peer.connectionState);}另請注意,有兩次成功連接,但我還沒有看到它再次工作。編輯:我忘了提到我也在創建一個數據通道(沒有這個事件似乎不會調用)。這將在構造并附加任何事件處理程序后立即調用。onicecandidateRTCPeerConnectionlet channel = peer.createDataChannel("...", {    id: ...,    ordered: true,});編輯2:正如@jib建議的那樣,我現在也在收集B中的冰候選者,并把他們送回A進行添加。但是,完全相同的問題仍然存在。編輯3:它似乎連接時,我第一次硬重新加載A的網頁和B的網頁.連接再次停止工作,直到我再做一次硬重新加載。有沒有人知道為什么會這樣?至少我應該能夠暫時繼續開發,直到我能弄清楚這個問題。編輯4:我刪除了我正在使用的構造函數,并將構造函數留空。不知何故,它現在更可靠了。但是我還沒有在iOS Safari上獲得成功的連接!iceServersRTCPeerConnection
查看完整描述

2 回答

?
POPMUISE

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


查看完整回答
反對 回復 2022-09-02
?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

最后!幾周后,我已經弄清楚了這個問題,這個問題在我的問題中包含的代碼中并不明顯,但對于遇到類似問題的人來說,它可能仍然有用。

我以為在活動結束后,冰上收集正在完成,并且提供了報價/答案。onnegotiationneeded

由于這個不正確的假設,我在這個階段與冰候選人一起發出報價/答案的信號,但是非常頻繁地(根據我的經驗,總是在iOS Safari中)此時尚未創建報價/答案。

我通過創建兩個承諾來解決這個問題:a)完成冰候選收集,以及b)創建報價/答案。我使用了兩個承諾,當它們都完成時,我通過信令服務器同時發送了冰候選者和提供/答案。Promise.all

這是可行的,但是當然在未來,我應該通過發送零碎的東西來“涓涓細流”這些信息,而不是等待一切完全完成。但是我將來會擔心這一點,因為目前我正在使用HTTP請求,而且這太麻煩了。

編輯:我的連接仍然總是卡住,所以我創建了一個新問題。但是,如果沒有本地連接,則現在100%完全可靠:)iceServersiceServers


查看完整回答
反對 回復 2022-09-02
  • 2 回答
  • 0 關注
  • 381 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號