reinício do cliente - .NET SDK
Nesta página
Visão geral
Novidades na versão 10.17.0.
Um erro de reinício do cliente é uma situação em que um Realm não consegue sincronizar dados com a aplicação backend. Clientes neste estado podem continuar executando e salvando dados localmente, mas não podem enviar ou receber conjuntos de alterações de sincronização até fazerem um reinício do cliente. Na maioria dos casos, SDKs do Realm oferecem métodos para gerenciar o reinício do cliente automaticamente.
Estratégias de reinício do cliente
Os cenários de redefinição de cliente ocorrem quando o histórico do servidor é incompatível com o histórico do cliente. As causas mais comuns de reinício do cliente são descritas em Reinícios do cliente.
No .NET SDK, você pode especificar uma estratégia de redefinição do cliente em seu FlexibleSyncConfiguration e PartitionSyncConfiguration. A propriedade ClientResetHandler pode ser definida como uma das seguintes:
Handler | Estratégia | Notas |
---|---|---|
RecoverOrDiscardUnsyncedChangesHandler (Default) | Recuperar todas as alterações locais não sincronizadas | Se a recuperação falhar, esse manipulador voltará para o DiscardUnsyncedChangesHandler , que exclui todas as alterações locais não sincronizadas. Se a recuperação DiscardUnsyncedChangesHandler falhar, o manipulador voltará para um ManualRecoveryHandler , o que exige que você implemente uma estratégia de recuperação manual. |
Recuperar todas as alterações locais não sincronizadas | Se a recuperação falhar, esse manipulador voltará para um ManualRecoveryHandler , o que exige que você implemente uma estratégia de recuperação manual. | |
Descartar alterações não sincronizadas | Essa estratégia exclui permanentemente todas as alterações locais não sincronizadas feitas desde a última sincronização bem-sucedida. | |
Recuperação manual | Fornece uma maneira de você implementar sua própria estratégia de recuperação. |
As seções a seguir descrevem as diferentes estratégias para lidar com uma redefinição de cliente e como você pode usar cada uma das ClientResetHandlers
.
Recuperar alterações locais não sincronizadas
Em um reinício do cliente que não envolve uma alteração de esquema de quebra, o SDK integra objeto criados localmente que não sincronizaram antes do reinício do cliente. As regras a seguir determinam como os conflitos são resolvidos quando o backend e o cliente fazem alterações no mesmo objeto:
Se um objeto for excluído no servidor, mas for modificado no cliente de recuperação, a exclusão terá precedência e o cliente descartará a atualização.
Se um objeto for excluído no cliente em recuperação, mas não no servidor, o cliente aplicará a instrução de exclusão.
No caso de atualizações conflitantes no mesmo campo, a atualização do cliente é aplicada.
Importante
Mudanças de última hora
O processo de recuperação não pode lidar com uma alteração significativa de esquema. Por exemplo, se você fizer uma alteração não aditiva em uma ou mais classes de Objeto de Realm , o processo de recuperação falhará. Nesse caso, os usuários precisarão atualizar seu aplicativo cliente . Para obter mais informações sobre alterações significativas, consulte Referência rápida de alterações significativas versus não significativas.
Há dois manipuladores de reinício do cliente que tentam recuperar automaticamente os dados locais não sincronizados: RecoverOrDiscardUnsyncedChangesHandler
e RecoverUnsyncedChangesHandler
.
RecuperarOrDiscardUnsyncedChangesHandler
Este é o manipulador padrão, pois fornece o processo de recuperação mais robusto. Se o processo de recuperação automática falhar, ele voltará para a estratégia DiscardLocalReset
explicada na seção Descartar alterações não sincronizadas. Se esse processo falhar, ele voltará para uma estratégia de reinício manual explicada na seção Recuperação manual. Este manipulador fornece os seguintes métodos de chamada de resposta:
OnBeforeReset, que o SDK invoca antes da redefinição do cliente. Você pode usar esse retorno de chamada para notificar o usuário antes que a redefinição do cliente comece.
OnAfterRecovery, que o SDK invoca se e somente se o reinício automático for concluído com êxito. Você pode usá-lo para notificar o usuário de que a reinício do cliente foi concluída.
OnAfterDiscard, que o SDK invoca somente se o reinício do cliente automático falhar e a estratégia local de descarte for bem-sucedida. Se a estratégia de descarte falhar, este chamada de resposta de chamada não será invocado.
ManualResetFallback, que o SDK invoca somente se a recuperação automática e a estratégia de descarte tiverem falhado. Você implementa esse chamada de resposta de chamada para lidar com a falha de redefinição. Sua lógica aqui deve ser semelhante à descrita para um ManualRecoveryHandler.
O exemplo a seguir mostra o uso de cada uma dessas chamadas de resposta:
var conf = new FlexibleSyncConfiguration(user) { ClientResetHandler = new RecoverOrDiscardUnsyncedChangesHandler { // The following callbacks are optional OnBeforeReset = (beforeReset) => { // Executed before the client reset begins // Can be used to notify the user that a reset is going // to happen }, OnAfterRecovery = (beforeReset, afterReset) => { // Executed after the client reset is complete // Can be used to notify the user that the reset is done }, OnAfterDiscard = (beforeReset, afterReset) => { // Executed if the automatic recovery has failed // but the DiscardUnsyncedChanges fallback has completed // successfully }, ManualResetFallback = (err) => { // Automatic reset failed; handle the reset manually here } } };
Recuperar alterações não sincronizadasHandler
Como o RecoverOrDiscardUnsyncedChangesHandler
, este manipulador tenta recuperar automaticamente todas as alterações locais não sincronizadas. No entanto, ao contrário RecoverOrDiscardUnsyncedChangesHandler
, esse manipulador não volta para DiscardUnsyncedChangesHandler
se a recuperação automática falhar. Em vez disso, ele retorna a uma estratégia de reinício manual explicada na seção Recuperação manual. O manipulador fornece os seguintes métodos de chamada de resposta de resposta:
OnBeforeReset, que você pode usar para notificar o usuário antes do início da redefinição.
OnAfterReset, que você pode usar para notificar o usuário quando a redefinição for concluída com êxito.
ManualResetFallback, que você implementa para lidar com uma falha de redefinição. Sua lógica aqui deve ser semelhante à descrita para um ManualRecoveryHandler.
O exemplo a seguir mostra o uso de cada uma dessas chamadas de resposta:
var conf = new FlexibleSyncConfiguration(user) { ClientResetHandler = new RecoverUnsyncedChangesHandler { // The following callbacks are optional OnBeforeReset = (beforeReset) => { // Executed before the client reset begins // Can be used to notify the user that a reset is going // to happen }, OnAfterReset = (beforeReset, afterReset) => { // Executed after the client reset is complete // Can be used to notify the user that the reset is done }, ManualResetFallback = (err) => { // Automatic reset failed; handle the reset manually here } } };
Descartar alterações não sincronizadas
Essa estratégia exclui permanentemente todas as alterações locais não sincronizadas feitas desde a última sincronização bem-sucedida. Se você optar por usar um DiscardUnsyncedChangesHandler
, o SDK restaurará seu arquivo de Realm local para um estado sincronizável sem fechar o Realm e, ao mesmo tempo, manter as notificações funcionando perfeitamente. Se esse processo falhar, ele voltará para uma estratégia de reinício manual explicada na seção Recuperação manual. Este manipulador fornece os seguintes métodos de chamada de resposta de resposta:
OnBeforeReset, que o SDK invoca antes da redefinição do cliente. Você pode usar esse retorno de chamada para notificar o usuário antes que a redefinição comece.
OnAfterReset, que o SDK invoca se e somente se a redefinição for concluída com êxito. Você pode usá-lo para notificar o usuário quando a redefinição for concluída.
ManualResetFallback, que o SDK invoca se a redefinição falhar. Sua lógica aqui deve ser semelhante à descrita para um ManualRecoveryHandler.
O exemplo a seguir mostra como você pode implementar um DiscardUnsyncedChangesHandler
:
{
var config = new FlexibleSyncConfiguration(user);
config.ClientResetHandler = new DiscardUnsyncedChangesHandler()
{
// The following callbacks are optional
OnBeforeReset = (beforeReset) =>
{ // Executed before the client reset begins // Can be used to notify the user that a reset is going // to happen },
OnAfterReset = (beforeReset, afterReset) => { // Executed after the client reset is complete // Can be used to notify the user that the reset is done },
ManualResetFallback = (err) =>
{ // Automatic reset failed; handle the reset manually here }
};
try {
var realm = await Realm.GetInstanceAsync(config); }
catch (Exception ex) { Console.WriteLine($@"Error creating or opening the realm file. {ex.Message}"); }
Recuperação manual
Na maioria dos casos, você deve usar uma das outras estratégias para redefinir o cliente . Para os casos pouco frequentes em que você precisa personalizar seu processo de recuperação de dados, selecione o manipulador ManualRecoveryHandler .
Observação
Recuos
Embora a estratégia manual só deva ser usada em casos extremos, os outros manipuladores de reinício do cliente podem voltar a uma estratégia manual. A lógica que você usa nesses manipuladores é semelhante à lógica descrita aqui.
Dentro do ManualRecoveryHandler
, você descarta o domínio existente e, em seguida, chama o método InitiateClientReset() .
O exemplo a seguir demonstra a implementação do ManualRecoveryHandler
:
private void SetupRealm()
{
var config = new FlexibleSyncConfiguration(user);
config.ClientResetHandler =
new ManualRecoveryHandler(HandleClientResetError);
var realm = await Realm.GetInstanceAsync(config);
}
private void HandleClientResetError(ClientResetException clientResetException)
{
Console.WriteLine($"Client Reset requested: {clientResetException.Message}");
// Prompt user to perform a client reset immediately. If they don't,
// they won't receive any data from the server until they restart the app
// and all changes they make will be discarded when the app restarts.
var didUserConfirmReset = ShowUserAConfirmationDialog();
if (didUserConfirmReset)
{
// Close the Realm before doing the reset. It must be
// deleted as part of the reset.
fsRealm.Dispose();
// perform the client reset
var didReset = clientResetException.InitiateClientReset();
if (didReset)
{
// Navigate the user back to the main page or reopen the
// the Realm and reinitialize the current page
}
else
{
// Reset failed - notify user that they'll need to
// update the app
}
}
}
Tratamento de reinício do cliente de teste
Você pode testar manualmente o tratamento de redefinição do cliente do seu aplicativo encerrando e reativando o Device Sync.
Quando você encerra e reativa a sincronização, os clientes que se conectaram anteriormente à sincronização não conseguem se conectar até depois de fazerem um reinício do cliente. O encerramento da sincronização exclui os metadados do servidor que permitem ao cliente sincronizar. O cliente deve baixar uma nova cópia do Realm do servidor. O servidor envia um erro de reinício do cliente para esses clientes. Então, ao encerrar a sincronização, você trigger a condição de reinício do cliente.
Para testar o tratamento de reinício do cliente:
Escreva dados de um aplicativo cliente e aguarde a sincronização.
Encerre e reative o Realm Mobile Sync.
Run the client app again. O aplicativo deve receber um erro de reinício do cliente ao tentar se conectar ao servidor.
Aviso
Enquanto você itera sobre o tratamento de redefinição do cliente em seu aplicativo cliente, talvez seja necessário encerrar e reativar a sincronização repetidamente. Encerrar e reativar a sincronização impede que todos os clientes existentes sincronizem até depois de concluir a redefinição do cliente. Para evitar isso na produção, teste o tratamento de redefinição do cliente em um ambiente de desenvolvimento.