Send acks before sending set active request

This commit is contained in:
Tulir Asokan 2024-03-05 13:11:27 +02:00
parent 94e59bbb3f
commit 96c09b4752
5 changed files with 19 additions and 14 deletions

View file

@ -8,7 +8,6 @@ import (
"io"
"net/http"
"net/url"
"sync/atomic"
"time"
"github.com/google/uuid"
@ -75,8 +74,6 @@ type Client struct {
conversationsFetchedOnce bool
hackyDelaySetActive atomic.Bool
AuthData *AuthData
cfg *gmproto.Config
@ -156,18 +153,19 @@ func (c *Client) Connect() error {
// return fmt.Errorf("failed to get web encryption key: %w", err)
//}
//c.updateWebEncryptionKey(webEncryptionKeyResponse.GetKey())
go c.doLongPoll(true)
go c.doLongPoll(true, c.postConnect)
c.sessionHandler.startAckInterval()
go c.postConnect()
return nil
}
func (c *Client) postConnect() {
// For some reason SetActiveSession fails if it's called immediately after reconnecting after a google login,
// so hackily delay it a few seconds to make it work.
if c.hackyDelaySetActive.CompareAndSwap(true, false) {
time.Sleep(3 * time.Second)
time.Sleep(2 * time.Second)
c.Logger.Debug().Msg("Sending acks before get updates request")
if c.skipCount > 0 {
c.Logger.Warn().Int("skip_count", c.skipCount).Msg("Skip count is still non-zero")
}
c.sessionHandler.sendAckRequest()
time.Sleep(1 * time.Second)
c.Logger.Debug().Msg("Sending get updates request")
err := c.SetActiveSession()
if err != nil {

View file

@ -205,7 +205,7 @@ func tryReadBody(resp io.ReadCloser) []byte {
return data
}
func (c *Client) doLongPoll(loggedIn bool) {
func (c *Client) doLongPoll(loggedIn bool, onFirstConnect func()) {
c.listenID++
listenID := c.listenID
listenReqID := uuid.NewString()
@ -304,6 +304,10 @@ func (c *Client) doLongPoll(loggedIn bool) {
log.Debug().Msg("Ditto pinger is still waiting for previous ping, skipping new ping")
}
}
if onFirstConnect != nil {
go onFirstConnect()
onFirstConnect = nil
}
c.readLongPoll(&log, resp.Body)
c.longPollingConn = nil
}

View file

@ -20,7 +20,7 @@ func (c *Client) StartLogin() (string, error) {
return "", err
}
c.updateTachyonAuthToken(registered.GetAuthKeyData())
go c.doLongPoll(false)
go c.doLongPoll(false, nil)
qr, err := c.GenerateQRCodeData(registered.GetPairingKey())
if err != nil {
return "", fmt.Errorf("failed to generate QR code: %w", err)

View file

@ -29,6 +29,7 @@ import (
"fmt"
"io"
"math/big"
"sync"
"time"
"github.com/google/uuid"
@ -267,7 +268,10 @@ func (c *Client) DoGaiaPairing(ctx context.Context, emojiCallback func(string))
return fmt.Errorf("failed to parse destination UUID: %w", err)
}
c.AuthData.DestRegID = destRegUUID
go c.doLongPoll(false)
var longPollConnectWait sync.WaitGroup
longPollConnectWait.Add(1)
go c.doLongPoll(false, longPollConnectWait.Done)
longPollConnectWait.Wait()
ps := NewPairingSession()
clientInit, clientFinish, err := ps.PreparePayloads()
if err != nil {
@ -300,7 +304,6 @@ func (c *Client) DoGaiaPairing(ctx context.Context, emojiCallback func(string))
c.AuthData.PairingID = ps.UUID
c.triggerEvent(&events.PairSuccessful{PhoneID: c.AuthData.Mobile.GetSourceID()})
c.hackyDelaySetActive.Store(true)
go func() {
// Sleep for a bit to let the phone save the pair data. If we reconnect too quickly,
// the phone won't recognize the session the bridge will get unpaired.

View file

@ -254,7 +254,7 @@ func (s *SessionHandler) queueMessageAck(messageID string) {
func (s *SessionHandler) startAckInterval() {
if s.ackTicker != nil {
s.ackTicker.Stop()
return
}
ticker := time.NewTicker(5 * time.Second)
s.ackTicker = ticker