Wait for ICE gathering completion before requesting video track + create file e2e test fix (#5193)
* Test main e2e * Create projects separately in home page tests I think creating them in Promise.all was introducing nondeterminism and making tests flaky. * Query the homepage projects in an order-insensitive way * Wait for ICE candidate gathering to complete before requesting video track * Update src/lang/std/engineConnection.ts Co-authored-by: Jonathan Tran <jonnytran@gmail.com> * Fix create file e2e failure * Yarn fmt * Fix typo: s/that/this yarn tsc was failing with this error: ``` src/lang/std/engineConnection.ts:1285:7 - error TS2304: Cannot find name 'that'. 1285 that.triggeredStart = false ~~~~ ``` * Fix up revolve tests * Turn off 3 flaky Windows tests * Fix tags --------- Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev> Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
This commit is contained in:
@ -248,6 +248,8 @@ class EngineConnection extends EventTarget {
|
||||
mediaStream?: MediaStream
|
||||
idleMode: boolean = false
|
||||
promise?: Promise<void>
|
||||
sdpAnswer?: Models['RtcSessionDescription_type']
|
||||
triggeredStart = false
|
||||
|
||||
onIceCandidate = function (
|
||||
this: RTCPeerConnection,
|
||||
@ -553,6 +555,7 @@ class EngineConnection extends EventTarget {
|
||||
* did not establish.
|
||||
*/
|
||||
connect(reconnecting?: boolean): Promise<void> {
|
||||
const that = this
|
||||
return new Promise((resolve) => {
|
||||
if (this.isConnecting() || this.isReady()) {
|
||||
return
|
||||
@ -583,8 +586,38 @@ class EngineConnection extends EventTarget {
|
||||
},
|
||||
}
|
||||
|
||||
const initiateConnectingExclusive = () => {
|
||||
if (that.triggeredStart) return
|
||||
that.triggeredStart = true
|
||||
|
||||
// Start connecting.
|
||||
that.state = {
|
||||
type: EngineConnectionStateType.Connecting,
|
||||
value: {
|
||||
type: ConnectingType.WebRTCConnecting,
|
||||
},
|
||||
}
|
||||
|
||||
// As soon as this is set, RTCPeerConnection tries to
|
||||
// establish a connection.
|
||||
// @ts-expect-error: Have to ignore because dom.ts doesn't have the right type
|
||||
void that.pc?.setRemoteDescription(that.sdpAnswer)
|
||||
|
||||
that.state = {
|
||||
type: EngineConnectionStateType.Connecting,
|
||||
value: {
|
||||
type: ConnectingType.SetRemoteDescription,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
this.onIceCandidate = (event: RTCPeerConnectionIceEvent) => {
|
||||
console.log('icecandidate', event.candidate)
|
||||
|
||||
// This is null when the ICE gathering state is done.
|
||||
// Windows ONLY uses this to signal it's done!
|
||||
if (event.candidate === null) {
|
||||
initiateConnectingExclusive()
|
||||
return
|
||||
}
|
||||
|
||||
@ -595,7 +628,6 @@ class EngineConnection extends EventTarget {
|
||||
},
|
||||
}
|
||||
|
||||
// Request a candidate to use
|
||||
this.send({
|
||||
type: 'trickle_ice',
|
||||
candidate: {
|
||||
@ -605,8 +637,38 @@ class EngineConnection extends EventTarget {
|
||||
usernameFragment: event.candidate.usernameFragment || undefined,
|
||||
},
|
||||
})
|
||||
|
||||
// Sometimes the remote end doesn't report the end of candidates.
|
||||
// They have 3 seconds to.
|
||||
setTimeout(() => {
|
||||
initiateConnectingExclusive()
|
||||
}, 3000)
|
||||
}
|
||||
this.pc?.addEventListener?.('icecandidate', this.onIceCandidate)
|
||||
this.pc?.addEventListener?.(
|
||||
'icegatheringstatechange',
|
||||
function (_event) {
|
||||
console.log('icegatheringstatechange', this.iceGatheringState)
|
||||
|
||||
if (this.iceGatheringState !== 'complete') return
|
||||
initiateConnectingExclusive()
|
||||
}
|
||||
)
|
||||
|
||||
this.pc?.addEventListener?.(
|
||||
'iceconnectionstatechange',
|
||||
function (_event) {
|
||||
console.log('iceconnectionstatechange', this.iceConnectionState)
|
||||
console.log('iceconnectionstatechange', this.iceGatheringState)
|
||||
}
|
||||
)
|
||||
this.pc?.addEventListener?.('negotiationneeded', function (_event) {
|
||||
console.log('negotiationneeded', this.iceConnectionState)
|
||||
console.log('negotiationneeded', this.iceGatheringState)
|
||||
})
|
||||
this.pc?.addEventListener?.('signalingstatechange', function (event) {
|
||||
console.log('signalingstatechange', this.signalingState)
|
||||
})
|
||||
|
||||
this.onIceCandidateError = (_event: Event) => {
|
||||
const event = _event as RTCPeerConnectionIceErrorEvent
|
||||
@ -634,6 +696,8 @@ class EngineConnection extends EventTarget {
|
||||
})
|
||||
)
|
||||
break
|
||||
case 'connecting':
|
||||
break
|
||||
case 'disconnected':
|
||||
case 'failed':
|
||||
this.pc?.removeEventListener('icecandidate', this.onIceCandidate)
|
||||
@ -1126,25 +1190,8 @@ class EngineConnection extends EventTarget {
|
||||
},
|
||||
}
|
||||
|
||||
// As soon as this is set, RTCPeerConnection tries to
|
||||
// establish a connection.
|
||||
// @ts-ignore
|
||||
// Have to ignore because dom.ts doesn't have the right type
|
||||
void this.pc?.setRemoteDescription(answer)
|
||||
this.sdpAnswer = answer
|
||||
|
||||
this.state = {
|
||||
type: EngineConnectionStateType.Connecting,
|
||||
value: {
|
||||
type: ConnectingType.SetRemoteDescription,
|
||||
},
|
||||
}
|
||||
|
||||
this.state = {
|
||||
type: EngineConnectionStateType.Connecting,
|
||||
value: {
|
||||
type: ConnectingType.WebRTCConnecting,
|
||||
},
|
||||
}
|
||||
break
|
||||
|
||||
case 'trickle_ice':
|
||||
@ -1235,6 +1282,7 @@ class EngineConnection extends EventTarget {
|
||||
if (closedPc && closedUDC && closedWS) {
|
||||
// Do not notify the rest of the program that we have cut off anything.
|
||||
this.state = { type: EngineConnectionStateType.Disconnected }
|
||||
this.triggeredStart = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user