Gerenciar uma sessão de sincronização - React Native SDK
Nesta página
Quando você usa o Atlas Device Sync, o React Native SDK sincroniza dados com o Atlas em segundo plano usando uma sessão de sincronização. Uma sessão de sincronização começa sempre que você abre um Realm sincronizado.
Pré-requisitos
Antes de managed uma sessão de sincronização, você deve executar o seguinte:
Envolva componentes que usam o hook
useRealm()
para um Realm sincronizado com os componentesAppProvider
,UserProvider
eRealmProvider
. Para obter mais informações sobre como configurar e abrir um Realm sincronizado, consulte Abrir um Realm sincronizado.
Acessar sessão de sincronização
Acesse um Realm sincronizado em um componente com o gancho useRealm()
. Acesse a sessão de sincronização com a propriedade Realm .syncSession do domínio.
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... } // ... }
Pausar ou retomar uma sessão de sincronização
Abrir um Realm sincronizado inicia uma sessão de sincronização. Você pode pausar e retomar a sessão de sincronização do domínio. Se você tiver mais de um Realm aberto , a pausa não afetará as sessões de sincronização dos outros domínios.
Para pausar a sincronização, use o Realm.syncSession.pause() método. Para retomar a sincronização, use o realm.syncSession.resume() método.
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} /> ); }
Quando pausar uma sessão de sincronização
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.
Verificar o progresso do upload e download de uma sessão de sincronização
Para verificar o progresso de upload e download de uma sessão de sincronização, adicione uma notificação de progresso usando o método .syncSession.addProgressNotification() do Realm método.
O método Realm.syncSession.addProgressNotification()
utiliza os seguintes três parâmetros:
Um parâmetro
direction
. Defina como"upload"
para registrar notificações de upload de dados. Defina como"download"
para registrar notificações para baixar dados.Um parâmetro
mode
. Defina como"reportIndefinitely"
para que as notificações continuem até que o registro da chamada de resposta seja cancelado usando Realm.syncSession.removeProgressNotification(). Defina como"forCurrentlyOutstandingWork"
para que as notificações continuem até que somente os bytes atualmente transferíveis sejam sincronizados.Um parâmetro de função de chamada de resposta que tem os argumentos
transferred
etransferable
.transferred
é o número atual de bytes já transferidos.transferable
é o número total de bytes já transferidos mais o número de bytes pendentes de transferência.
Observação
As notificações de progresso da Flexible Sync ainda não são totalmente suportadas. Ao usar a Flexible Sync, os downloads só relatam notificações após a integração das alterações. A sincronização baseada em partição fornece notificações contínuas à medida que o download das alterações progride. Os carregamentos relatam notificações de progresso contínuo para ambos os modos de sincronização.
O exemplo a seguir registra uma chamada de resposta no syncSession
para escutar evento de upload indefinidamente. O exemplo grava no Realm e, em seguida, cancela o registro da chamada de resposta de notificação 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>; }
Verifique a conexão de rede
O design offline do Realm significa que geralmente você não precisa verificar o estado atual da conexão de rede, pois os dados são sincronizados em segundo plano quando uma conexão está disponível. Dito isto, o Realm SDK fornece métodos para obter o estado atual da conexão de rede com o servidor.
Para verificar o estado atual da conexão com o servidor, chame Realm.syncSession.isConnected(). Este método retorna um booleano que é true
se houver uma conexão de rede e a sessão de sincronização estiver ativa.
Para ouvir as alterações no estado da conexão, chame Realm.syncSession.addConnectionNotification(), passando uma função de retorno de chamada para lidar com as alterações de rede como argumento. Para cancelar o registro do ouvinte, passe a mesma função de retorno de chamada de resposta para 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> ); }
Sessões de sincronização multiplex
Habilitar multiplexação de sessão para consolidar múltiplas sessões de sincronização de um aplicativo Realm . Use a multiplexação de sessão somente se ver erros ao atingir o limite do descritor de arquivos e saber que está usando muitas sessões de sincronização.
Para habilitar a multiplexação de sessão, chame Realm.App.Sync.enableSessionMultitexing() com seu 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>; }