Realms sincronizados
You can configure a realm to automatically synchronize data between many devices that each have their own local copy of the data. Synced realms use a different configuration than local-only realms and require an Atlas App Services backend to handle the synchronization process.
Las aplicaciones siempre pueden crear, modificar y eliminar objetos de dominio sincronizados localmente, incluso sin conexión. Siempre que haya una conexión de red disponible, el SDK de dominio abre una conexión con un servidor de aplicaciones y sincroniza los cambios con y desde otros clientes. El protocolo Atlas Device Sync y las transformaciones operativas del lado del servidor garantizan que todas las instancias totalmente sincronizadas de un reino vean exactamente los mismos datos, incluso si algunos cambios ocurrieron sin conexión y/o se recibieron fuera de orden.
Tip
Learn How to Configure and Use Sync
For more information on Device Sync, including directions on how to set up sync in an App Services app, see Sync Data Between Devices - .NET SDK.
Synced Realms vs. Non-Synced Realms
Synced realms differ from non-synced local Realm in a couple of ways:
Synced realms attempt to sync changes with your backend App Services App, whereas non-synced realms do not.
Synced realms can be accessed by authenticated users, while non-synced realms have no concept of users or authentication.
You can copy data from a non-synced realm to a synced realm, and vice versa, but you cannot sync a non-synced realm.
Convert Between Synced and Non-Synced Realms
To convert a non-synced realm to a synced realm, you can follow the process described in Migrate a Local-Only App to a Sync-Enabled App. The .NET SDK also provides the WriteCopy() method, which enables you to duplicate a non-synced realm's data to a sync realm. For more information, refer to Migrate from Non-Synced Realms to Synced Realms.
Nota
Partition-Based Sync Only
This method only supports converting between a non-sync realm and Partition-Based Sync. If your app uses Flexible Sync, you must manually iterate through the objects in one realm and copy them into the other realm.
Realms sincronizados
Para abrir un dominio sincronizado, debe tener un objeto de usuario autenticado. Para obtener una inicial User Por ejemplo, debe autenticarse en el backend de Atlas App Services, lo que requiere que el dispositivo esté en línea la primera vez que un usuario inicia sesión. Una vez que se ha producido la autenticación inicial, puede recuperar un usuario existente mientras está desconectado.
Nota
The first time a user logs on to your app, you should open the realm asynchronously to sync data from the server to the device in a background thread. After that initial sync, you can open a realm synchronously to ensure the app works in an offline state.
Open a Synced Realm
The typical flow for opening a synced realm involves:
Creando una configuración de sincronización.
Abrir el realm sincronizado del usuario con la configuración.
Durante la autenticación, almacenamos en caché las credenciales de los usuarios en un archivo sync_metadata.realm en el dispositivo.
When you open a synced realm after authenticating, you can bypass the login flow and go directly to opening the synced realm, using the same sync configuration you already created.
With cached credentials, you can:
Open a synced realm immediately with the data that is on the device. You can use this method offline or online.
Open a synced realm after downloading changes from your App. This requires the user to have an active internet connection.
Open a Synced Realm While Online
Los pasos para abrir un realm sincronizado mientras estás en linea son:
Your app code walks the user through authenticating.
Crea un objeto FlexibleSyncConfiguration que incluya el objeto Usuario.
Abra un reino sincronizado llamando al método GetInstanceAsync().
Si tu FlexibleSyncConfiguration no contiene suscripciones iniciales, añade una suscripción.
El siguiente código demuestra estos pasos:
var app = App.Create("myRealmAppId"); var user = await app.LogInAsync(Credentials.Anonymous()); Realm realm; var config = new FlexibleSyncConfiguration(user) { PopulateInitialSubscriptions = (realm) => { var allTasks = realm.All<MyTask>(); realm.Subscriptions.Add(allTasks, new SubscriptionOptions { Name = "allTasks" }); } }; try { realm = await Realm.GetInstanceAsync(config); } catch (Exception ex) { Console.WriteLine($@"Error creating or opening the realm file. {ex.Message}"); }
In the above example, the code shows how to open the realm asynchronously by calling GetInstanceAsync(). You can also open a realm synchronously by calling the GetInstance() method:
var synchronousRealm = Realm.GetInstance(config);
Open a Synced Realm While Offline
Once a user authenticates, the User object persists on the device until the user logs off. This allows your app to retrieve an existing user and open a synced realm in an offline state. Changes that occur while offline will be synced by the SDK once the device reconnects to your App.
El siguiente código muestra cómo comprobar si existe un objeto User. Si no hay ninguno, utiliza el proceso que se indica arriba para obtener un usuario. Si el dispositivo ya tiene un user, se abre el realm sincronizado con ese usuario:
var app = App.Create("myRealmAppId"); Realms.Sync.User user; FlexibleSyncConfiguration config; Realm realm; if (app.CurrentUser == null) { // App must be online for user to authenticate user = await app.LogInAsync(Credentials.Anonymous()); config = new FlexibleSyncConfiguration(user); realm = Realm.GetInstance(config); // Go on to add or update subscriptions and use the realm } else { // This works whether online or offline // It requires a user to have been previously authenticated user = app.CurrentUser; config = new FlexibleSyncConfiguration(user); realm = Realm.GetInstance(config); // Go on to add or update subscriptions and use the realm }
Configuring Timeouts with AppConfiguration
Para un control detallado de la conexión de su aplicación, puede configurar SyncTimeoutOptions en el objeto AppConfiguration. Puede configurar las siguientes propiedades de tiempo de espera de sincronización:
ConnectTimeout: the amount of time to allow for a connection to become fully established.ConnectionLingerTime: the amount of time to keep a connection open after all sessions have been abandoned.PingKeepAlivePeriod: the amount of time between each heartbeat ping messagePongKeepAliveTimeout: el tiempo de espera para recibir una respuesta a un ping de latidos antes de concluir que la conexión se perdió.FastReconnectLimit: el tiempo transcurrido desde la pérdida de una conexión anterior para que una nueva conexión se considere una "reconexión rápida".
AppConfiguration configuration = new AppConfiguration("myRealmAppId") { SyncTimeoutOptions = new SyncTimeoutOptions() { ConnectTimeout = TimeSpan.FromMinutes(2), ConnectionLingerTime = TimeSpan.FromSeconds(30), PingKeepAlivePeriod = TimeSpan.FromMinutes(1), PongKeepAliveTimeout = TimeSpan.FromMinutes(1), FastReconnectLimit = TimeSpan.FromMinutes(1), }, };
Scoping the Realm
The realm instance implements IDisposable to ensure native resources are freed up. You should dispose of a realm object immediately after use, especially on background threads. The simplest way to do this is by declaring the realm object with a using statement, or wrapping the code that interacts with a realm in a using (...) statement:
config = new PartitionSyncConfiguration("myPart", user); using (var realm = Realm.GetInstance(config)) { var allItems = realm.All<Item>(); }
If you require a realm object to be shared outside of a single method, be sure to manage its state by calling the Dispose() method:
realm.Dispose();
Nota
As a general rule, you should dispose of the realm only on background threads, because disposing of a realm invalidates all objects associated with that instance. If you are data binding the realm objects on the main thread, for example, you should not call Dispose().
Class Subsets
Por defecto, todas las clases RealmObject se almacenan en un realm. En algunos escenarios, puede que desees limitar las clases que se almacenan, lo cual puedes hacer con la propiedad Schema del objeto RealmConfiguration. El siguiente código demuestra cómo se especifican dos clases que se desea almacenar en el realm:
var config = new RealmConfiguration() { Schema = new Type[] { typeof(AClassWorthStoring), typeof(AnotherClassWorthStoring) } };