Al usar Atlas Device Sync, el SDK de Flutter sincroniza los datos con Atlas en segundo plano mediante una sesión de sincronización. Esta sesión se inicia al abrir un dominio sincronizado.
La sesión de sincronización gestiona lo siguiente:
Cargar y descargar cambios en la base de datos sincronizada
Pausar y reanudar la sincronización
Monitoreo del progreso de la sincronización
Monitoreo de la conectividad de la red
Puedes acceder a la Sesiónde cualquier reino sincronizado a través de la propiedad Realm.syncSession.
Requisitos previos
Antes de poder administrar el estado de su sesión de sincronización, debe realizar lo siguiente:
Espera a que los cambios se suban y se descarguen
Para esperar asincrónicamente a que todos los cambios se carguen a Atlas desde el dominio sincronizado, llama a Session.waitForUpload(). Para esperar asincrónicamente a que todos los cambios en Atlas se descarguen a tu dominio 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();
Pausar y reanudar una sesión de sincronización
Para pausar la sincronización de una sesión, llame a Session.pause(). El dominio no sincronizará los cambios con Atlas mientras la sesión esté pausada.
Para reanudar la sincronización de cambios, llame a Session.resume().
Debes llamar manualmente a Session.pause() y Session.resume() para cada reino cuya sesión de sincronización quieras pausar y reiniciar. El estado de sincronización de una sesión no afecta a las demás 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
En la mayoría de las aplicaciones, no es necesario pausar y reanudar manualmente una sesión de sincronización. Sin embargo, existen algunas circunstancias en las que podría ser conveniente pausar o suspender una sesión de sincronización:
Solo desea sincronizar después de que el usuario realice una acción específica
Solo desea sincronizar durante un momento determinado del día.
No debes intentar sincronizar cuando hay una mala conectividad de red
Quiere forzar explícitamente una sesión de sincronización para conectarse
En el caso de una mala conectividad de red, intentar continuamente establecer una conexión de red puede agotar la batería del dispositivo del usuario.
El caso de forzar explícitamente la conexión de una sesión de sincronización suele estar relacionado con estar desconectado durante un tiempo. El cliente de sincronización intenta conectarse y, al fallar, entra en una fase de desconexión exponencial. Tras un tiempo prolongado desconectado, es posible que el cliente no se vuelva a conectar inmediatamente. Pausar y reanudar la sesión de sincronización fuerza explícitamente la conexión.
Cuando pause una sesión de sincronización, tenga en cuenta lo siguiente:
Si el cliente puede estar fuera de línea por un tiempo mayor al máximo permitido, no podrá reanudar la sincronización y deberá reiniciarlo.
Pausar una sesión de sincronización la pausa en ambos sentidos. Los cambios que realiza la aplicación en el dispositivo no se sincronizan con el backend, y los cambios en los datos del backend o de otros dispositivos no se sincronizan con el dispositivo. No es posible pausar solo las cargas ni las descargas.
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 pause la sincronización para detenerla por períodos indefinidos o intervalos de tiempo de meses o años. Esta función no está diseñada ni probada para estos casos de uso. Podría experimentar diversos problemas al usarla 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
Para supervisar el progreso de la sincronización, llame a SyncSession.getProgressStream(). Este método devuelve un flujo de objetos SyncProgress que proporcionan un progressEstimate para la carga o descarga actual.
El progressEstimate proporcionado es un valor doble cuyo valor oscila entre 0.0 y 1.0. En 1.0, el flujo de progreso se completa.
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:Establece que las notificaciones continúen hasta que se cancele el registro de la devolución de llamada.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.
Monitorear la conexión de red
Puede obtener el estado de la conexión de red actual con Session.connectionState. Esto devuelve una enumeración ConnectionState que contiene el estado de la conexión deconnected red:, disconnected connectingo.
if (realm.syncSession.connectionState == ConnectionState.connected) { // ... do stuff }
Supervise el estado de la conexión de red con Session.connectionStateChanges. Esta propiedad devuelve un flujo de objetos ConnectionStateChange que se actualiza cuando cambia la conexión de red. Puede acceder al actual y al anterior ConnectionState ConnectionStateChangedesde.
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.
Puede optar por activar manualmente un intento de reconexión con App.reconnect() en lugar de esperar a que finalice el retroceso incremental. Esto es útil si comprende mejor las condiciones de la red y no desea depender de la detección automática de reconexión.
app.reconnect();
Cuando se llama a este método, el SDK fuerza a todas las sesiones de sincronización a intentar reconectarse inmediatamente y restablece todos los temporizadores utilizados para el retroceso incremental.
Importante
No se puede reconectar dentro del tiempo de espera de lectura del socket
El SDK de Flutter tiene un tiempo de espera de lectura de socket predeterminado interno de minutos. El tiempo de espera 2 se agota si una operación de lectura no recibe datos en un 2período de minutos. Si se llama App.Sync.reconnect() a dentro de ese período, el SDK de Flutter no intenta reconectarse.