diff --git a/client/internal/peer/conn.go b/client/internal/peer/conn.go index 86e4596d4..8df9aa700 100644 --- a/client/internal/peer/conn.go +++ b/client/internal/peer/conn.go @@ -205,6 +205,12 @@ func (conn *Conn) Open(engineCtx context.Context) error { conn.guard.Start(conn.ctx, conn.onGuardEvent) }() + + // both peer send offer + if err := conn.handshaker.SendOffer(); err != nil { + conn.Log.Errorf("failed to send offer: %v", err) + } + conn.opened = true return nil } diff --git a/client/internal/peer/guard/guard.go b/client/internal/peer/guard/guard.go index d93403730..b85ec02fa 100644 --- a/client/internal/peer/guard/guard.go +++ b/client/internal/peer/guard/guard.go @@ -4,7 +4,6 @@ import ( "context" "time" - "github.com/cenkalti/backoff/v4" log "github.com/sirupsen/logrus" ) @@ -63,75 +62,26 @@ func (g *Guard) reconnectLoopWithRetry(ctx context.Context, callback func()) { srReconnectedChan := g.srWatcher.NewListener() defer g.srWatcher.RemoveListener(srReconnectedChan) - ticker := g.initialTicker(ctx) - defer ticker.Stop() - - tickerChannel := ticker.C - for { select { - case t := <-tickerChannel: - if t.IsZero() { - g.log.Infof("retry timed out, stop periodic offer sending") - // after backoff timeout the ticker.C will be closed. We need to a dummy channel to avoid loop - tickerChannel = make(<-chan time.Time) - continue - } - + case <-g.relayedConnDisconnected: + g.log.Debugf("Relay connection changed, reset reconnection ticker") if !g.isConnectedOnAllWay() { callback() } - case <-g.relayedConnDisconnected: - g.log.Debugf("Relay connection changed, reset reconnection ticker") - ticker.Stop() - ticker = g.prepareExponentTicker(ctx) - tickerChannel = ticker.C - case <-g.iCEConnDisconnected: g.log.Debugf("ICE connection changed, reset reconnection ticker") - ticker.Stop() - ticker = g.prepareExponentTicker(ctx) - tickerChannel = ticker.C - + if !g.isConnectedOnAllWay() { + callback() + } case <-srReconnectedChan: g.log.Debugf("has network changes, reset reconnection ticker") - ticker.Stop() - ticker = g.prepareExponentTicker(ctx) - tickerChannel = ticker.C - + if !g.isConnectedOnAllWay() { + callback() + } case <-ctx.Done(): g.log.Debugf("context is done, stop reconnect loop") return } } } - -// initialTicker give chance to the peer to establish the initial connection. -func (g *Guard) initialTicker(ctx context.Context) *backoff.Ticker { - bo := backoff.WithContext(&backoff.ExponentialBackOff{ - InitialInterval: 3 * time.Second, - RandomizationFactor: 0.1, - Multiplier: 2, - MaxInterval: g.timeout, - Stop: backoff.Stop, - Clock: backoff.SystemClock, - }, ctx) - - return backoff.NewTicker(bo) -} - -func (g *Guard) prepareExponentTicker(ctx context.Context) *backoff.Ticker { - bo := backoff.WithContext(&backoff.ExponentialBackOff{ - InitialInterval: 800 * time.Millisecond, - RandomizationFactor: 0.1, - Multiplier: 2, - MaxInterval: g.timeout, - Stop: backoff.Stop, - Clock: backoff.SystemClock, - }, ctx) - - ticker := backoff.NewTicker(bo) - <-ticker.C // consume the initial tick what is happening right after the ticker has been created - - return ticker -} diff --git a/client/internal/peer/handshaker.go b/client/internal/peer/handshaker.go index 42eaea683..e4e23253f 100644 --- a/client/internal/peer/handshaker.go +++ b/client/internal/peer/handshaker.go @@ -79,11 +79,14 @@ func (h *Handshaker) Listen(ctx context.Context) { for { select { case remoteOfferAnswer := <-h.remoteOffersCh: - // received confirmation from the remote peer -> ready to proceed - if err := h.sendAnswer(); err != nil { - h.log.Errorf("failed to send remote offer confirmation: %s", err) - continue + + if isController(h.config) { + if err := h.sendAnswer(); err != nil { + h.log.Errorf("failed to send remote offer confirmation: %s", err) + continue + } } + for _, listener := range h.onNewOfferListeners { listener.Notify(&remoteOfferAnswer) }