Ressourcen effizient synchronisieren

In diesem Leitfaden wird beschrieben, wie Sie die inkrementelle Synchronisierung von Kalenderdaten implementieren. Mit dieser Methode können Sie die Daten für alle Kalendersammlungen synchronisieren und gleichzeitig Bandbreite sparen.

Inhalt

Übersicht

Die inkrementelle Synchronisierung besteht aus zwei Phasen:

  1. Erste vollständige Synchronisierung: Wird einmal am Anfang ausgeführt, um den Clientstatus vollständig mit dem Serverstatus zu synchronisieren. Der Client erhält ein Synchronisierungstoken, das er beibehalten muss.

  2. Inkrementelle Synchronisierung: Wird wiederholt ausgeführt, um den Client mit allen Änderungen zu aktualisieren, die seit der letzten Synchronisierung vorgenommen wurden. Jedes Mal stellt der Client das vorherige Synchronisierungstoken vom Server bereit 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 enthält die Antwort ein Feld mit dem Namen nextSyncToken, das ein Synchronisierungstoken darstellt. Sie müssen den Wert von nextSyncToken speichern. Wenn das Ergebnis zu groß ist und die Antwort paginiert ist, 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. Führen Sie dazu eine Listenanfrage mit dem neuesten Synchronisierungstoken aus, das im Feld syncToken angegeben ist. Beachten Sie, dass das Ergebnis immer gelöschte Einträge enthält, damit 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. Führen Sie in diesen Fällen dieselbe Listenabfrage aus, die zum Abrufen der ersten Seite in der inkrementellen Synchronisierung verwendet wurde (mit demselben syncToken), fügen Sie das pageToken hinzu und paginieren Sie durch nachfolgende Anfragen, bis Sie auf der letzten Seite ein weiteres syncToken finden. Speichern Sie dieses syncToken für die nächste Synchronisierungsanfrage.

Die folgenden Beispiele zeigen eine inkrementelle paginierte Synchronisierung:

Ursprüngliche Abfrage

GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx

Das Ergebnis enthält Folgendes:

{
  "nextPageToken": "CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA"
}

Nächste Seite abrufen

GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx&pageToken=CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA

Vom Server erforderliche vollständige Synchronisierung

Der Server macht Synchronisierungstokens manchmal ungültig, weil sie abgelaufen sind oder sich die zugehörigen ACLs geändert haben. In solchen Fällen antwortet der Server auf eine inkrementelle Anfrage mit dem HTTP-Statuscode 410. Löschen Sie in diesem Fall den Clientspeicher und führen Sie eine neue vollständige Synchronisierung durch.

Beispielcode

Im folgenden Beispiel wird gezeigt, 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 können Sie die ältere Synchronisierung durchführen, indem Sie den Wert des updated Felds aus einer Ereignislistenanfrage speichern und dann das updatedMin Feld verwenden, um aktualisierte Ereignisse abzurufen. Diese Methode wird nicht mehr empfohlen, da sie fehleranfälliger ist (z. B. werden keine Abfrageeinschränkungen erzwungen) und nur für Ereignisse verfügbar ist.