使用 Atlas Device Sync 时,Flutter SDK 使用同步会话在后台与 Atlas 同步数据。 每当您打开同步 Realm 时,同步会话就会启动。
同步会话管理以下内容:
上传和下载对同步数据库的更改
暂停和恢复同步
监控同步进度
监控网络连接
You can access the Session of any synced realm through the Realm.syncSession property.
先决条件
在托管同步会话状态之前,您必须执行以下操作:
等待更改上传和下载
To asynchronously wait for all changes to upload to Atlas from your synced realm, call Session.waitForUpload(). To asynchronously wait for all changes on Atlas to download to your synced realm, call 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();
You can add an optional CancellationToken to waitForUpload()
and waitForDownload()
.
final cancellationToken = CancellationToken(); final waitForDownloadFuture = realm.syncSession.waitForDownload(cancellationToken); cancellationToken.cancel(); final waitForUploadFuture = realm.syncSession.waitForUpload(cancellationToken); cancellationToken.cancel();
暂停和恢复同步会话
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().
您必须为要暂停和重新启动同步会话的每个 Realm 手动调用Session.pause()
和Session.resume()
。 一个会话的同步状态对其他打开的会话没有影响。
以下代码块演示了如何调用这些方法:
// 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();
何时暂停同步会话
对于大多数应用程序,无需手动暂停和恢复同步会话。 但是,在某些情况下,您可能希望暂停或暂停同步会话:
您只想在用户执行特定操作后进行同步
您只想在一天中的特定时间进行同步
您不想在网络连接较差时尝试同步
您想要显式强制同步会话连接
在网络连接较差的情况下,不断尝试建立网络连接可能会耗尽用户的设备电池。
显式强制同步会话连接的情况最常见与离线一段时间有关。同步客户端尝试连接,一旦失败,就会Go指数退避状态。长时间离线后,客户端可能无法立即重新连接。 暂停和恢复同步会话会显式强制连接。
当您暂停同步会话时,请记住以下事项:
暂停同步会话会使其在两个方向上暂停。您的应用在设备上所做的更改不会与后端同步,对后端或其他设备上的数据的更改也不会同步到设备。 无法仅暂停上传或仅暂停下载。
如果您希望客户端永久停止与后端同步,请勿暂停同步会话。 要永久停止同步,请将同步 Realm 的内容复制到非同步 Realm,并在客户端中使用该非同步 Realm。
请勿在不确定的时间段或以月和年为单位的时间范围内通过暂停同步来停止同步。 该功能不是针对这些使用案例而设计或测试的。 以这种方式使用时,您可能会遇到一系列问题。
监控同步上传和下载进度
在版本2.0.0中进行了更改: 已弃用transferredBytes
和transferrableBytes
,改用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.
提供的progressEstimate
是一个双精度值,其值范围为0.0
到1.0
。 在1.0
时,进度流已完成。
SyncSession.getProgressStream()
有两个参数:
A ProgressDirection enum that can be set to
upload
ordownload
. Specifies whether the progress stream monitors upload or download progress.A ProgressMode enum that can be set to one of the following:
reportIndefinitely
:将通知设置为继续,直到取消注册回调。forCurrentlyOutstandingWork
:将通知设置为继续,直到progressEstimate
达到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(); });
提示
您还可以在首次打开Realm时使用onProgressCallback配置同步监控。
监控网络连接
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 }
Monitor the state of the network connection with Session.connectionStateChanges. This property returns a Stream of ConnectionStateChange objects that updates when the network connection changes. You can access the current and previous ConnectionState
from 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(); } });
手动重新连接所有同步会话
Flutter SDK 会自动检测设备何时在离线后重新获得连接,并尝试使用增量退避策略重新连接。
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();
调用此方法时,SDK 会强制所有同步会话立即尝试重新连接,并重置用于增量退避的任何计时器。
重要
无法在套接字读取超时时间内重新连接
Flutter SDK 的内部默认套接字读取超时为 2 分钟,如果读取操作在 2 分钟窗口内未收到任何数据,SDK 将超时。 如果您在该窗口内调用App.Sync.reconnect()
,Flutter SDK不会尝试重新连接。