handle ICE restart and candidate gathering race

This commit is contained in:
David Zhao committed 2021-05-15 17:31:48 -07:00
1 parent 6a99146c21
commit e3854eaff4
3 files changed
+28 -7

No files matched your search

+1
View File
@@ -6,6 +6,7 @@ locals {
port_range_end = var.udp_port_end
tcp_port = var.rtc_tcp_port
udp_port = var.rtc_udp_port
use_external_ip = true
}
turn = {
enabled = var.turn_enabled
+26 -6
View File
@@ -30,10 +30,11 @@ type PCTransport struct {
pc *webrtc.PeerConnection
me *webrtc.MediaEngine
lock sync.Mutex
pendingCandidates []webrtc.ICECandidateInit
debouncedNegotiate func(func())
onOffer func(offer webrtc.SessionDescription)
lock sync.Mutex
pendingCandidates []webrtc.ICECandidateInit
debouncedNegotiate func(func())
onOffer func(offer webrtc.SessionDescription)
restartAfterGathering atomic.Value
negotiationState atomic.Value
}
@@ -90,7 +91,15 @@ func NewPCTransport(params TransportParams) (*PCTransport, error) {
debouncedNegotiate: debounce.New(negotiationFrequency),
}
t.negotiationState.Store(negotiationStateNone)
//t.pc.OnNegotiationNeeded(t.Negotiate)
t.pc.OnICEGatheringStateChange(func(state webrtc.ICEGathererState) {
if state == webrtc.ICEGathererStateComplete {
if restart, ok := t.restartAfterGathering.Load().(bool); ok && restart {
if err := t.CreateAndSendOffer(&webrtc.OfferOptions{ICERestart: true}); err != nil {
logger.Warnw("could not restart ICE", "error", err)
}
}
}
})
return t, nil
}
@@ -160,12 +169,22 @@ func (t *PCTransport) CreateAndSendOffer(options *webrtc.OfferOptions) error {
return nil
}
iceRestart := options != nil && options.ICERestart
// if restart is requested, and we are not ready, then continue afterwards
if iceRestart && t.pc.ICEGatheringState() == webrtc.ICEGatheringStateGathering {
logger.Debugw("restart ICE after gathering")
t.restartAfterGathering.Store(true)
return nil
}
state := t.negotiationState.Load().(int)
logger.Debugw("restarting ICE")
// when there's an ongoing negotiation, let it finish and not disrupt its state
if state == negotiationStateClient {
currentSD := t.pc.CurrentRemoteDescription()
if options != nil && options.ICERestart && currentSD != nil {
if iceRestart && currentSD != nil {
logger.Debugw("recovering from client negotiation state")
if err := t.pc.SetRemoteDescription(*currentSD); err != nil {
return err
@@ -191,6 +210,7 @@ func (t *PCTransport) CreateAndSendOffer(options *webrtc.OfferOptions) error {
// indicate waiting for client
t.negotiationState.Store(negotiationStateClient)
t.restartAfterGathering.Store(false)
t.onOffer(offer)
return nil
+1 -1
View File
@@ -1,3 +1,3 @@
package version
const Version = "0.9.2"
const Version = "0.9.3"