Gerenciar uma sessão de sincronização - SDK Flutter
Nesta página
Quando você usa o Atlas Device Sync, o Flutter SDK sincroniza dados com o Atlas em segundo plano usando uma sessão de sincronização. A sessão de sincronização começa sempre que você abre um domínio sincronizado.
A sessão de sincronização managed o seguinte:
Enviando e baixando alterações no banco de dados sincronizado
Pausando e retomando a sincronização
Monitoramento do progresso da sincronização
Monitoramento da conectividade de rede
Você pode acessar a Sessão de qualquer Realm sincronizado através do Realm.syncSession propriedade.
Pré-requisitos
Antes de managed o estado da sessão de sincronização, você deve fazer o seguinte:
Aguarde as alterações para fazer upload e download
Para esperar de forma assíncrona que todas as alterações sejam carregadas no Atlas a partir do seu domínio sincronizado, chame Session.waitForUpload(). Para esperar de forma assíncrona que todas as alterações no Atlas sejam baixadas para seu domínio sincronizado, chame Session.waitForDownload().
// Wait to download all pending changes from Atlas await realm.syncSession.waitForDownload(); // Add data locally realm.write(() { realm.addAll<Car>([ Car(ObjectId(), "Hyundai"), Car(ObjectId(), "Kia"), Car(ObjectId(), "Lincoln") ]); }); // Wait for changes to upload to Atlas before continuing execution. await realm.syncSession.waitForUpload();
Você pode adicionar um CancellationToken opcional para waitForUpload()
e waitForDownload()
.
final cancellationToken = CancellationToken(); final waitForDownloadFuture = realm.syncSession.waitForDownload(cancellationToken); cancellationToken.cancel(); final waitForUploadFuture = realm.syncSession.waitForUpload(cancellationToken); cancellationToken.cancel();
Pausar e retomar uma sessão de sincronização
Para pausar a sincronização para uma sessão, chame Session.pause(). O domínio não sincronizará as alterações com o Atlas enquanto a sessão estiver pausada.
Para retomar a sincronização de alterações, chame Session.resume().
Você deve chamar manualmente Session.pause()
e Session.resume()
para cada realm cuja sessão de sincronização você deseja pausar e reiniciar. O estado de sincronização de uma sessão não tem impacto em outras sessões abertas.
O seguinte bloco de código demonstra a chamada destes métodos:
// Pause the sync session realm.syncSession.pause(); // Data that you add while the sync session is paused does not sync to Atlas. // However, the data is still added to the realm locally. realm.write(() { realm.addAll<Car>([ Car(ObjectId(), "Volvo"), Car(ObjectId(), "Genesis"), Car(ObjectId(), "VW") ]); }); // Resume sync session. Now, the data you wrote to the realm // syncs to Atlas. realm.syncSession.resume();
Quando pausar uma sessão de sincronização
Para a maioria dos aplicativos, não é necessário pausar e retomar manualmente uma sessão de sincronização. No entanto, existem algumas circunstâncias em que você pode querer pausar ou suspenso uma sessão de sincronização:
Você só quer sincronizar depois que o usuário executar uma ação específica
Você só deseja sincronizar durante um determinado horário do dia
Você não quer tentar sincronizar quando a conectividade de rede estiver ruim
Você deseja forçar explicitamente uma sessão de sincronização para se conectar
No caso de uma conectividade de rede ruim, tentar continuamente estabelecer uma conexão de rede pode esgotar a bateria do dispositivo do usuário.
O caso de forçar explicitamente uma sessão de sincronização para se conectar é mais comumente relacionado a estar offline por algum tempo. O cliente de sincronização tenta se conectar e, em caso de falha, entra em backoff exponencial. After being offline for a long time, the client may not immediately reconnect. Pausar e retomar a sessão de sincronização força explicitamente a conexão.
Ao pausar uma sessão de sincronização, lembre-se do seguinte:
Se o cliente ficar offline por mais tempo do que o tempo máximo offline do cliente , o cliente não conseguirá retomar a sincronização e deverá fazer um reinício do cliente.
Pausar uma sessão de sincronização a pausa em ambas as direções. As alterações feitas pelo seu aplicativo no dispositivo não são sincronizadas com o backend, e as alterações nos dados no backend ou em outros dispositivos não são sincronizadas com o dispositivo. Não há como pausar apenas uploads ou pausar apenas downloads.
Não pause uma sessão de sincronização se quiser que um cliente pare permanentemente de sincronizar com o backend. Para parar permanentemente a sincronização, copie o conteúdo do Realm sincronizado em um Realm não sincronizado e use o Realm não sincronizado no cliente.
Não pause a sincronização para parar a sincronização por períodos indefinidos ou intervalos de tempo em meses e anos. A funcionalidade não foi projetada ou testada para esses casos de uso. Você pode encontrar uma série de problemas ao usá-lo dessa forma.
Monitore o progresso do upload e download da sincronização
Alterado na versão 2.0.0: transferredBytes
e transferrableBytes
preteridos a favor de progressEstimate
Para monitorar o progresso da sincronização, chame SyncSession.getProgressStream(). Este método retorna um fluxo de SyncProgress objetos que fornecem um progressEstimate
para o upload ou download atual.
O progressEstimate
fornecido é um duplo cujo valor varia de 0.0
a 1.0
. Em 1.0
, o fluxo de progresso está completo.
SyncSession.getProgressStream()
recebe dois argumentos:
Uma direção de progresso enum que pode ser definido
upload
como oudownload
. Especifica se o fluxo de progresso monitora o progresso do upload ou download.Um ProgressMode enum que pode ser definido como um dos seguintes:
reportIndefinitely
: define as notificações para continuar até que a chamada de resposta seja cancelada.forCurrentlyOutstandingWork
: define as notificações para continuar até que oprogressEstimate
atinja1.0
.
final stream = realm.syncSession.getProgressStream( ProgressDirection.upload, ProgressMode.forCurrentlyOutstandingWork); double progressEstimate = -1; late StreamSubscription streamListener; streamListener = stream.listen((syncProgressEvent) { progressEstimate = syncProgressEvent.progressEstimate; if (progressEstimate < 1.0) { print('Upload progress: ${progressEstimate * 100}%'); } }, onDone: () { print('Upload progress: ${progressEstimate * 100}%'); print("Upload complete"); }, onError: (error) { print("An error occurred: $error"); streamListener.cancel(); });
Dica
Você também pode configurar o monitoramento de sincronização usando o onProgressCallback quando abrir um Realm pela primeira vez.
Monitorar conexão de rede
Você pode obter o estado da conexão de rede atual com Session.connectionState. Isso retorna um ConnectionState enum que contém o estado da conexão de rede: connected
, disconnected
ou connecting
.
if (realm.syncSession.connectionState == ConnectionState.connected) { // ... do stuff }
Monitore o estado da conexão de rede com Session.connectionStateChanges. Esta propriedade retorna um fluxo de ConnectionStateChange objetos que são atualizados quando a conexão de rede é alterada. Você pode acessar o ConnectionState
atual e anterior de ConnectionStateChange
.
final connectionStream = realm.syncSession.connectionStateChanges; late StreamSubscription streamListener; streamListener = connectionStream.listen((connectionStateChange) { if (connectionStateChange.current == ConnectionState.connected) { print("Connected to Atlas Device Sync server"); streamListener.cancel(); } });
Reconectar manualmente todas as sessões de sincronização
O SDK do Flutter detecta automaticamente quando um dispositivo recupera a conectividade depois de estar offline e tenta se reconectar usando uma estratégia de backoff incremental.
Você pode optar por manualmente trigger uma tentativa de reconexão com o App.reconnect() em vez de esperar pela duração do backoff incremental. Isso é útil se você tiver uma compreensão mais precisa das condições da rede e não quiser confiar na detecção automática de reconexão.
app.reconnect();
Quando você chama esse método, o SDK força todas as sessões de sincronização a tentar se reconectar imediatamente e redefine todos os cronômetros usados para backoff incremental.
Importante
Não é possível reconectar dentro da duração do tempo limite de leitura do soquete
O Flutter SDK tem um tempo limite de leitura de soquete padrão interno de 2 minutos, onde o Flutter SDK atingirá o tempo limite se uma operação de leitura não receber nenhum dado dentro de uma janela de 2 minutos. Se você chamar App.Sync.reconnect()
dentro dessa janela, o Flutter SDK não tentará se reconectar.