Menu Docs
Página inicial do Docs
/ /
Atlas Device SDKs
/ /

Gerenciar uma sessão de sincronização - SDK Flutter

Nesta página

  • Pré-requisitos
  • Aguarde as alterações para fazer upload e download
  • Pausar e retomar uma sessão de sincronização
  • Quando pausar uma sessão de sincronização
  • Monitore o progresso do upload e download da sincronização
  • Monitorar conexão de rede
  • Reconectar manualmente todas as sessões de sincronização

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.

Antes de managed o estado da sessão de sincronização, você deve fazer o seguinte:

  1. Configurar o Flexible Sync no backend do Atlas App Services

  2. Adicionar Device Sync ao seu aplicativo

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();

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();

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.

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 ou download. 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 o progressEstimate atinja 1.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.

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();
}
});

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.

Voltar

Gravar dados em um domínio sincronizado