Cuando usas Atlas Device Sync, el SDK de Flutter sincroniza datos con Atlas en segundo plano mediante una sesión de sincronización. La sesión de sincronización comienza cada vez que abres un realm sincronizado.
The sync session manages the following:
Cargando y descargando cambios en la base de datos sincronizada
Pausar y reanudar la sincronización
Monitoring sync progress
Monitoring network connectivity
Puedes acceder a la sesiónde cualquier reino sincronizado a través de la propiedad Realm.syncSession.
Requisitos previos
Before you can manage your sync session state, you must perform the following:
Espera a que los cambios se suban y se descarguen
Para esperar de forma asíncrona que todos los cambios se suban a Atlas desde tu realm sincronizado, llama a Session.waitForUpload(). Para esperar de forma asincrónica a que todos los cambios en Atlas se descarguen a tu realm sincronizado, llama a 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();
Puede agregar un CancellationToken opcional a waitForUpload() y waitForDownload().
final cancellationToken = CancellationToken(); final waitForDownloadFuture = realm.syncSession.waitForDownload(cancellationToken); cancellationToken.cancel(); final waitForUploadFuture = realm.syncSession.waitForUpload(cancellationToken); cancellationToken.cancel();
Pause and Resume a Sync Session
To pause syncing for a session, call Session.pause(). The realm will not sync changes with Atlas while the session is paused.
To resume syncing a changes, call Session.resume().
Debes llamar manualmente a Session.pause() y Session.resume() para cada realm cuya sesión de sincronización desees pausar y reiniciar. El estado de sincronización de una sesión no tiene impacto sobre otras sesiones abiertas.
El siguiente bloque de código demuestra cómo llamar a estos 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();
Cuándo pausar una sesión de sincronización
For most applications, there is no need to manually pause and resume a sync session. However, there are a few circumstances under which you may want to pause or suspend a sync session:
You only want to sync after the user takes a specific action
You only want to sync during a certain time of the day
No debes intentar sincronizar cuando hay una mala conectividad de red
You want to explicitly force a sync session to connect
In the case of poor network connectivity, continually trying to establish a network connection can drain the user's device battery.
The case of explicitly forcing a sync session to connect is most commonly related to being offline for some time. The sync client attempts to connect, and upon failure, goes into exponential backoff. After being offline for a long time, the client may not immediately reconnect. Pausing and resuming the sync session explicitly forces the connection.
When you do pause a sync session, keep these things in mind:
If the client may be offline longer than the client maximum offline time, the client will be unable to resume syncing and must perform a client reset.
Pausing a sync session pauses it in both directions. Changes that your app makes on the device do not sync with the backend, and changes to the data in the backend or on other devices do not sync to the device. There is no way to pause only uploads or pause only downloads.
No pause una sesión de sincronización si desea que un cliente deje de sincronizarse permanentemente con el backend. Para ello, copie el contenido del dominio sincronizado en uno no sincronizado y utilice este último en el cliente.
No pauses la sincronización para detener la sincronización por períodos de tiempo indefinidos o rangos de meses y años. La funcionalidad no está diseñada ni probada para estos casos de uso. Podrías encontrar un rango de problemas al usarlo de esta manera.
Supervisar el progreso de carga y descarga de sincronización
Cambiado en la 2.0.0 versión: transferredBytes y quedaron transferrableBytes obsoletos en favor de progressEstimate
To monitor Sync progress, call SyncSession.getProgressStream(). This method returns a Stream of SyncProgress objects that provide a progressEstimate for the current upload or download.
The provided progressEstimate is a double whose value ranges from 0.0 to 1.0. At 1.0, the progress stream is complete.
SyncSession.getProgressStream() toma dos argumentos:
Una enumeración ProgressDirection que puede establecerse
uploadendownloado. Especifica si el flujo de progreso supervisa el progreso de carga o descarga.Una enumeración ProgressMode que se puede configurar en uno de los siguientes:
reportIndefinitely: Sets notifications to continue until the callback is unregistered.forCurrentlyOutstandingWork:Establece que las notificaciones continúen hasta queprogressEstimatellegue a1.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(); });
Tip
También puedes configurar la monitorización de sincronización mediante onProgressCallback cuando abres un Reino por primera vez.
Monitor Network Connection
You can get the state of the current network connection with Session.connectionState. This returns a ConnectionState enum that contains the network connection's state: connected, disconnected, or connecting.
if (realm.syncSession.connectionState == ConnectionState.connected) { // ... do stuff }
Supervisa el estado de la conexión de red con Session.connectionStateChanges. Esta propiedad retorna un Stream de objetos ConnectionStateChange que se actualizan cuando la conexión de red cambia. Puedes acceder al ConnectionState actual y anterior desde 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 las sesiones de sincronización
El SDK de Flutter detecta automáticamente cuando un dispositivo recupera la conectividad después de estar sin conexión e intenta volver a conectarse utilizando una estrategia de backoff incremental.
You can choose to manually trigger a reconnect attempt with the App.reconnect() instead of waiting for the duration of the incremental backoff. This is useful if you have a more accurate understanding of the network conditions and don't want to rely on automatic reconnect detection.
app.reconnect();
Al llamar a este método, el SDK obliga a que todas las sesiones de sincronización intenten reconectarse inmediatamente y restablece cualquier temporizador utilizado para el retroceso incremental.
Importante
Cannot Reconnect Within Socket Read Timeout Duration
The Flutter SDK has an internal default socket read timeout of 2 minutes, where the SDK will time out if a read operation does not receive any data within a 2-minute window. If you call App.Sync.reconnect() within that window, the Flutter SDK does not attempt to reconnect.