diff --git a/client/src/renderstreaming.js b/client/src/renderstreaming.js index 52cbef1..a42f7df 100644 --- a/client/src/renderstreaming.js +++ b/client/src/renderstreaming.js @@ -75,10 +75,11 @@ export class RenderStreaming { if (this._isHost) { // host端:为该participant创建或复用peer + // host端始终使用polite=false(impolite),确保perfect negotiation中host的offer优先 let peer = this._peers.get(participantId); if (!peer || (peer.pc && peer.pc.iceConnectionState === 'disconnected')) { if (peer) peer.close(); - peer = this._preparePeerConnection(this._connectionId, offer.polite, participantId); + peer = this._preparePeerConnection(this._connectionId, false, participantId); } const desc = new RTCSessionDescription({ sdp: offer.sdp, type: "offer" }); try { @@ -87,13 +88,13 @@ export class RenderStreaming { Logger.warn(`Error on GotDescription for participant ${participantId}: ${error}`); } } else { - // participant端:使用单一peer + // participant端:使用单一peer,始终使用polite=true if (this._peer && this._peer.pc && this._peer.pc.iceConnectionState === 'disconnected') { this._peer.close(); this._peer = null; } if (!this._peer) { - this._preparePeerConnection(offer.connectionId, offer.polite, null); + this._preparePeerConnection(offer.connectionId, true, null); } const desc = new RTCSessionDescription({ sdp: offer.sdp, type: "offer" }); try { @@ -171,10 +172,9 @@ export class RenderStreaming { const participantId = data.participantId; Logger.log(`Participant joined: ${participantId}`); - // host端:为新participant创建peer - if (this._isHost && !this._peers.has(participantId)) { - this._preparePeerConnection(this._connectionId, false, participantId); - } + // host端:不在此处创建peer,等待participant的offer到达后在_onOffer中创建 + // 这样避免host和participant同时发offer导致的glare冲突 + // _onOffer会在收到participant的offer时自动创建peer(如果不存在) this.onParticipantJoined(participantId); } diff --git a/src/class/websockethandler.ts b/src/class/websockethandler.ts index 2acf2de..53eb5cb 100644 --- a/src/class/websockethandler.ts +++ b/src/class/websockethandler.ts @@ -239,7 +239,8 @@ function onOffer(ws: WebSocket, message: any): void { } } else { // participant发送offer给host,携带该participant的participantId - newOffer.polite = true; + // host端应为impolite(polite=false),确保perfect negotiation中host优先 + newOffer.polite = false; group.host.send(JSON.stringify({ from: connectionId, to: "", type: "offer", data: newOffer, participantId: senderParticipantId })); } }