In diesem Leitfaden wird beschrieben, wie Sie die „inkrementelle Synchronisierung“ von Kalenderdaten implementieren. Mit dieser Methode können Sie Daten für alle Kalendersammlungen synchron halten und gleichzeitig Bandbreite sparen.
Inhalt
Übersicht
Die inkrementelle Synchronisierung besteht aus zwei Phasen:
Die erste vollständige Synchronisierung wird einmal ganz am Anfang durchgeführt, um den Clientstatus vollständig mit dem Serverstatus zu synchronisieren. Der Client erhält ein Synchronisierungstoken, das er beibehalten muss.
Die inkrementelle Synchronisierung wird wiederholt durchgeführt und aktualisiert den Client mit allen Änderungen, die seit der letzten Synchronisierung vorgenommen wurden. Jedes Mal stellt der Client das vorherige Synchronisierungstoken bereit, das er vom Server erhalten hat, und speichert das neue Synchronisierungstoken aus der Antwort.
Erste vollständige Synchronisierung
Die erste vollständige Synchronisierung ist die ursprüngliche Anfrage für alle Ressourcen der Sammlung, die Sie synchronisieren möchten. Optional können Sie die Listenanfrage mit Anfrageparametern einschränken, wenn Sie nur eine bestimmte Teilmenge von Ressourcen synchronisieren möchten.
In der Antwort auf den Listenvorgang finden Sie ein Feld namens
nextSyncToken das ein Synchronisierungstoken darstellt. Sie müssen den Wert von
nextSyncToken speichern. Wenn das Ergebnis zu groß ist und die Antwort
paginiertwird, ist das nextSyncToken
Feld nur auf der letzten Seite vorhanden.
Inkrementelle Synchronisierung
Mit der inkrementellen Synchronisierung können Sie alle Ressourcen abrufen, die seit der letzten Synchronisierungsanfrage geändert wurden. Dazu müssen Sie eine Listen
anfrage mit Ihrem letzten Synchronisierungstoken im Feld syncToken ausführen.
Beachten Sie, dass das Ergebnis immer gelöschte Einträge enthält, damit die Clients sie aus dem Speicher entfernen können.
Wenn sich seit der letzten
inkrementellen Synchronisierungsanfrage eine große Anzahl von Ressourcen geändert hat, finden Sie im Ergebnis möglicherweise ein pageToken anstelle eines syncToken. In diesem Fall müssen Sie genau dieselbe
Listenabfrage ausführen, die zum Abrufen der ersten Seite bei der inkrementellen Synchronisierung verwendet wurde
(mit genau demselben syncToken), das pageToken anhängen und
alle nachfolgenden Anfragen durchlaufen, bis Sie auf der letzten Seite ein weiteres syncToken finden. Speichern Sie dieses syncToken für die nächste Synchronisierungs
anfrage.
Hier sind Beispielabfragen für einen Fall, in dem eine inkrementelle paginierte Synchronisierung erforderlich ist:
Ursprüngliche Abfrage
GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx
// Result contains the following
"nextPageToken":"CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA",
Nächste Seite abrufen
GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx&pageToken=CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA
Vom Server erforderliche vollständige Synchronisierung
Manchmal werden Synchronisierungstokens aus verschiedenen Gründen vom Server ungültig gemacht, z. B. weil das Token abgelaufen ist oder sich die zugehörigen ACLs geändert haben.
In solchen Fällen antwortet der Server auf eine inkrementelle Anfrage mit einem
Antwortcode 410. Dadurch sollte der Speicher des Clients vollständig gelöscht und eine neue vollständige Synchronisierung ausgelöst werden.
Beispielcode
Das folgende Code-Snippet zeigt, wie Sie Synchronisierungstokens mit der Java-Clientbibliothek verwenden. Wenn die Methode „run“ zum ersten Mal aufgerufen wird, wird eine vollständige Synchronisierung durchgeführt und das Synchronisierungstoken gespeichert. Bei jeder nachfolgenden Ausführung wird das gespeicherte Synchronisierungstoken geladen und eine inkrementelle Synchronisierung durchgeführt.
private static void run() throws IOException { // Construct the {@link Calendar.Events.List} request, but don't execute it yet. Calendar.Events.List request = client.events().list("primary"); // Load the sync token stored from the last execution, if any. String syncToken = syncSettingsDataStore.get(SYNC_TOKEN_KEY); if (syncToken == null) { System.out.println("Performing full sync."); // Set the filters you want to use during the full sync. Sync tokens aren't compatible with // most filters, but you may want to limit your full sync to only a certain date range. // In this example we are only syncing events up to a year old. Date oneYearAgo = Utils.getRelativeDate(java.util.Calendar.YEAR, -1); request.setTimeMin(new DateTime(oneYearAgo, TimeZone.getTimeZone("UTC"))); } else { System.out.println("Performing incremental sync."); request.setSyncToken(syncToken); } // Retrieve the events, one page at a time. String pageToken = null; Events events = null; do { request.setPageToken(pageToken); try { events = request.execute(); } catch (GoogleJsonResponseException e) { if (e.getStatusCode() == 410) { // A 410 status code, "Gone", indicates that the sync token is invalid. System.out.println("Invalid sync token, clearing event store and re-syncing."); syncSettingsDataStore.delete(SYNC_TOKEN_KEY); eventDataStore.clear(); run(); } else { throw e; } } List<Event> items = events.getItems(); if (items.size() == 0) { System.out.println("No new events to sync."); } else { for (Event event : items) { syncEvent(event); } } pageToken = events.getNextPageToken(); } while (pageToken != null); // Store the sync token from the last request to be used during the next execution. syncSettingsDataStore.set(SYNC_TOKEN_KEY, events.getNextSyncToken()); System.out.println("Sync complete."); }
Ältere Synchronisierung
Für Ereignissammlungen ist es weiterhin möglich, die Synchronisierung auf die
herkömmliche Weise durchzuführen, indem der Wert des Felds „updated“ aus einer Ereignislistenanfrage beibehalten und dann das modifiedSince Feld verwendet wird, um aktualisierte Ereignisse abzurufen.
Diese Methode wird nicht mehr empfohlen, da sie fehleranfälliger ist, was verpasste Aktualisierungen betrifft (z. B. wenn keine Abfrageeinschränkungen erzwingt).
Außerdem ist sie nur für Ereignisse verfügbar.