管理同步会话 — React Native SDK
当您使用 Atlas Device Sync 时,React Native SDK 使用同步会话在背景与 Atlas 同步数据。每当您打开同步 Realm 时,同步会话就会启动。
先决条件
在托管同步会话之前,您必须执行以下操作:
包装使用
useRealm()
钩子实现具有AppProvider
、UserProvider
和RealmProvider
组件的同步域的组件。有关配置和打开同步 Realm 的更多信息,请参阅打开同步 Realm。
Access 同步会话
使用useRealm()
钩子访问组件中的同步域 。 使用 Realm 的 Realm.syncSession属性访问同步会话。
import React, {useEffect} from 'react'; import {Context} from '../RealmConfig'; const {useRealm} = Context; function AccessSyncSession() { const realm = useRealm(); async function workWithSyncSession() { const {syncSession} = realm; // Do stuff with sync session... } // ... }
暂停或恢复同步会话
打开同步域会启动同步会话。 您可以暂停和恢复 Realm 的同步会话。 如果您有多个打开的域,暂停不会影响其他 Realm 的同步会话。
要暂停同步,请使用Realm.syncSession.pause() 方法。 要恢复同步,请使用Realm.syncSession.resume() 方法。
import React, {useEffect, useState} from 'react'; import {Context} from '../RealmConfig'; const {useRealm} = Context; function ToggleSyncSession() { const realm = useRealm(); const [isPaused, setIsPaused] = useState(false); async function toggleSyncSession() { if (isPaused) { await realm.syncSession?.resume(); } else { await realm.syncSession?.pause(); } setIsPaused(!isPaused); } return ( <Button title={isPaused ? 'Pause Sync' : 'Unpause Sync'} onPress={toggleSyncSession} /> ); }
何时暂停同步会话
对于大多数应用程序,无需手动暂停和恢复同步会话。 但是,在某些情况下,您可能希望暂停或暂停同步会话:
您只想在用户执行特定操作后进行同步
您只想在一天中的特定时间进行同步
您不想在网络连接较差时尝试同步
您想要显式强制同步会话连接
在网络连接较差的情况下,不断尝试建立网络连接可能会耗尽用户的设备电池。
显式强制同步会话连接的情况最常见与离线一段时间有关。同步客户端尝试连接,一旦失败,就会Go指数退避状态。长时间离线后,客户端可能无法立即重新连接。 暂停和恢复同步会话会显式强制连接。
当您暂停同步会话时,请记住以下事项:
暂停同步会话会使其在两个方向上暂停。您的应用在设备上所做的更改不会与后端同步,对后端或其他设备上的数据的更改也不会同步到设备。 无法仅暂停上传或仅暂停下载。
如果您希望客户端永久停止与后端同步,请勿暂停同步会话。 要永久停止同步,请将同步 Realm 的内容复制到非同步 Realm,并在客户端中使用该非同步 Realm。
请勿在不确定的时间段或以月和年为单位的时间范围内通过暂停同步来停止同步。 该功能不是针对这些使用案例而设计或测试的。 以这种方式使用时,您可能会遇到一系列问题。
检查同步会话的上传和下载进度
要检查同步会话的上传和下载进度,请使用Realm添加进度通知。 方法。
Realm.syncSession.addProgressNotification()
方法接受以下三个参数:
一个
direction
参数。 设置为"upload"
以注册上传数据的通知。 设置为"download"
以注册下载数据的通知。一个
mode
参数。 设置为"reportIndefinitely"
以使通知继续,直到使用Realm.syncSession.removeProgressNotification()取消注册回调。 设置为"forCurrentlyOutstandingWork"
以使通知继续,直到仅同步当前可传输的字节。回调函数参数,其参数为
transferred
和transferable
。transferred
是当前已传输的字节数。transferable
是已传输的字节总数加上待传输的字节数。
注意
尚不完全支持 Flexible Sync 进度通知。 使用Flexible Sync时,仅在集成更改后下载报告通知。 基于分区的同步在下载变更时提供持续通知。 上传报告两种同步模式的持续进度通知。
以下示例在syncSession
上注册回调以无限期地侦听上传事件。 该示例会写入 Realm,然后取消注册syncSession
通知回调。
import React, {useEffect, useState} from 'react'; import {SyncedRealmContext} from '../RealmConfig'; const {useRealm} = SyncedRealmContext; import {Text} from 'react-native'; function CheckUploadProgress() { const realm = useRealm(); const [uploadProgressPercent, setUploadProgressPercent] = useState(0); useEffect(() => { const progressNotificationCallback = (transferred, transferable) => { // Convert decimal to percent with no decimals // (e.g. 0.6666... -> 67) const percentTransferred = parseFloat((transferred / transferable).toFixed(2)) * 100; setUploadProgressPercent(percentTransferred); }; // Listen for changes to connection state realm.syncSession?.addProgressNotification( Realm.ProgressDirection.Upload, Realm.ProgressMode.ReportIndefinitely, progressNotificationCallback, ); // Remove the connection listener when component unmounts return () => realm.syncSession?.removeProgressNotification( progressNotificationCallback, ); // Run useEffect only when component mounts }, []); return <Text>Percent Uploaded: {uploadProgressPercent} %</Text>; }
import React, {useEffect, useState} from 'react'; import {Context} from '../RealmConfig'; const {useRealm} = Context; import {Text} from 'react-native'; function CheckUploadProgress() { const realm = useRealm(); const [uploadProgressPercent, setUploadProgressPercent] = useState(0); useEffect(() => { const progressNotificationCallback: Realm.ProgressNotificationCallback = ( transferred, transferable, ) => { // Convert decimal to percent with no decimals // (e.g. 0.6666... -> 67) const percentTransferred = parseFloat((transferred / transferable).toFixed(2)) * 100; setUploadProgressPercent(percentTransferred); }; // Listen for changes to connection state realm.syncSession?.addProgressNotification( Realm.ProgressDirection.Upload, Realm.ProgressMode.ReportIndefinitely, progressNotificationCallback, ); // Remove the connection listener when component unmounts return () => realm.syncSession?.removeProgressNotification( progressNotificationCallback, ); // Run useEffect only when component mounts }, []); return <Text>Percent Uploaded: {uploadProgressPercent} %</Text>; }
检查网络连接
Realm 的离线优先设计意味着您通常不需要检查当前的网络连接状态,因为当连接可用时,数据会在背景同步。也就是说,Realm 软件开发工具包(Realm SDK)提供了获取服务器网络连接当前状态的方法。
要检查与服务器的当前连接状态,请调用Realm.syncSession.isConnected() 。 如果存在网络连接并且同步会话处于活动状态,则此方法会返回布尔值true
。
要侦听连接状态更改,请调用Realm.syncSession.addConnectionNotification() 、 将处理网络更改的回调函数作为参数传递。 要取消注册监听器,请将相同的回调函数传递给Realm.syncSession.removeConnectionNotification()。
import React, {useState, useEffect} from 'react'; import {SyncedRealmContext} from '../RealmConfig'; const {useRealm} = SyncedRealmContext; import {Text} from 'react-native'; function CheckNetworkConnection() { const realm = useRealm(); const [isConnected, setIsConnected] = useState( realm.syncSession?.isConnected(), ); useEffect(() => { const connectionNotificationCallback = (newState, oldState) => { console.log('Current connection state: ' + newState); console.log('Previous connection state: ' + oldState); setIsConnected(realm.syncSession?.isConnected()); }; // Listen for changes to connection state realm.syncSession?.addConnectionNotification( connectionNotificationCallback, ); // Remove the connection listener when component unmounts return () => realm.syncSession?.removeConnectionNotification( connectionNotificationCallback, ); // Run useEffect only when component mounts }, []); return ( <Text> {isConnected ? 'Connected to Network' : 'Disconnected from Network'} </Text> ); }
import React, {useState, useEffect} from 'react'; import {Context} from '../RealmConfig'; const {useRealm} = Context; import {Text} from 'react-native'; function CheckNetworkConnection() { const realm = useRealm(); const [isConnected, setIsConnected] = useState( realm.syncSession?.isConnected(), ); useEffect(() => { const connectionNotificationCallback: Realm.ConnectionNotificationCallback = (newState, oldState) => { console.log('Current connection state: ' + newState); console.log('Previous connection state: ' + oldState); setIsConnected(realm.syncSession?.isConnected()); }; // Listen for changes to connection state realm.syncSession?.addConnectionNotification( connectionNotificationCallback, ); // Remove the connection listener when component unmounts return () => realm.syncSession?.removeConnectionNotification( connectionNotificationCallback, ); // Run useEffect only when component mounts }, []); return ( <Text> {isConnected ? 'Connected to Network' : 'Disconnected from Network'} </Text> ); }
多路复用同步会话
启用 会话多路复用 来整合Realm应用的多个同步会话。仅当看到有关达到文件限制的错误,并且知道正在使用许多同步会话时,才使用会话多路复用。
要启用会话多路复用,请调用Realm.App.Sync.enableSessionMultiplexing() 与您的Realm.App 一起使用。
import React, {useEffect} from 'react'; import {Context} from '../RealmConfig'; import {AppProvider, UserProvider, useUser, useApp, Realm} from '@realm/react'; function AppWrapper() { return ( <AppProvider id={APP_ID}> <UserProvider fallback={<LogIn />}> <RealmWrapper> <RestOfApp /> </RealmWrapper> </UserProvider> </AppProvider> ); } type RealmWrapperProps = { children: React.ReactNode; }; function RealmWrapper({children}: RealmWrapperProps) { const app = useApp(); Realm.App.Sync.enableSessionMultiplexing(app); return <RealmProvider sync={{flexible: true}}>{children}</RealmProvider>; }