Muss schnell los. Schnelle IMAP-E-Mail-Synchronisierung

Hallo! Ich heiße Ilya. Vor zwei Jahren bin ich dem IMAP Mobile Client beigetreten. Frühere Versionen der Anwendung haben die Liste der Briefe lange Zeit heruntergeladen und viel Verkehr für die Aktualisierung des Postfachs aufgewendet. Es stellte sich die Frage nach der Optimierung der Arbeit mit dem Protokoll und nach den Fähigkeiten dieses Protokolls im Allgemeinen. Ich wusste nichts über das Protokoll und stürzte mich in das Lesen der Dokumentation. Es stellt sich heraus, dass der Client das Protokoll die ganze Zeit ohne Unterbrechung verwendet hat und die Implementierungsfunktionen überhaupt nicht berücksichtigt hat. Diese Funktionen haben dazu beigetragen, das Herunterladen von E-Mails um das Zwei- bis Dreifache zu beschleunigen. Was IMAP ist und welche Chips es später in meinem Artikel zur Optimierung gibt.

Ich werde nicht zu tief in das Protokoll eintauchen. Ein Artikel eher aus der Kategorie "Ich möchte diesen Artikel vor zwei Jahren lesen." Es ist unwahrscheinlich, dass IMAP-Gurus neue Informationen für sich finden. Dieser Artikel basiert auf der Protokollbeschreibung von RFC 3501 .

Serververbindung


IMAP ist ein Stateful-Protokoll. Dies war eine Entdeckung für mich, bevor ich solche Protokolle nicht gesehen oder damit gearbeitet hatte. Betrachten Sie das Schema der Arbeit mit dem Server. 


Gehen wir der Reihe nach und vor allem mit Beispielen. Zuerst müssen Sie eine Verbindung zum Server herstellen. Verwenden Sie dazu die openSSL-Bibliothek.

openssl s_client -connect imap.server.com:993 -crlf 

Gut, die Verbindung ist hergestellt und Sie können die OK-Antwort mit einer Zeile beobachten, die mit der CAPABILITY-Antwort beginnt

OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE  SPECIAL-USE AUTH=PLAIN AUTH=LOGIN]

Für jede CAPABILITY gibt es einen praktischen Spickzettel , in dem alle möglichen CAPABILITY-Werte mit Links zum RFC geschrieben sind. Beispielsweise teilt IMAP4rev1 dem Client mit, dass der Server gemäß dem IMAP4-Standard arbeitet, und IDLE signalisiert, dass Sie Änderungen abonnieren können, die im Postfach auftreten.

Serverautorisierung


Nachdem Sie eine Verbindung zum Server hergestellt haben, müssen Sie zu Ihrer Mailbox gehen. Dies erfolgt mit dem Befehl LOGIN.

a1 LOGIN email pass

Also, hör auf, logge dich ein, ich verstehe, und a1 was ist das? - Vielleicht fragst du. Und das ist das Team-Tag. Im Interesse des Kunden sollten die Tags unterschiedlich sein, da die Antwort mit demselben Tag wie die Anforderung eingeht, was bedeutet, dass sie für das Parsen zwischen Teams abgeglichen werden kann. Der Server kann auch eine Antwort mit einem Sternchen am Anfang zurückgeben, z. B. * OK. Dies wird als Antwort ohne Tags bezeichnet. Grundsätzlich wird eine solche Antwort für Teams zurückgegeben, die mehrere Entitäten in der Antwort erwarten, z. B. LIST. 

Ordnerlistenanforderung


Um eine Liste von Buchstaben in einem Ordner anzufordern, müssen Sie zuerst diese Ordner herausfinden. Dies erfolgt mit dem Befehl LIST. Dieser Befehl gibt eine Liste der Ordner auf dem Server zurück.

A2 LIST «» *
* LIST (\HasNoChildren \Trash) «/» Trash
* LIST (\HasNoChildren \Sent) «/» Sent
* LIST (\HasNoChildren \Drafts) «/» Drafts
* LIST (\HasNoChildren \Junk) «/» Junk
* LIST (\HasNoChildren) «/» INBOX
A2 OK List completed (0.001 + 0.000 + 0.001 secs).

Der erste Parameter im Befehl ist der Namespace. Wenn der Server einen Namespace unterstützt, können seine Werte mithilfe der NAMESPACE-Abfrage angefordert werden. Der Standard-Namespace sieht aus wie eine leere Zeichenfolge. Als nächstes kommt der Platzhalterparameter ins Spiel. Damit können wir dem Server mitteilen, welche Ordner wir zurückgeben müssen. Zum Beispiel können wir erhalten: einen Ordnerbaumzweig, nur Wurzeln oder einfach alles, wie im obigen Beispiel. Es ist besser, dies nicht zu tun, denn wer weiß, wie viele Ordner der Benutzer in der Box hat. Die Autoren des Protokolls empfehlen die Verwendung von "%". In diesem Fall erhalten Sie alle Ordner der obersten Ebene aus dem Postfach. 

Aus der Antwort geht hervor, dass dies eine Antwort ohne Tags ist, bei der jede Zeile Ihr Ordner in der Box ist. Erstens gibt es Flags, mit denen wir die Metainformationen des Ordners lesen. In diesem Beispiel haben alle Ordner keine Nachkommen und einige Spezialordner (wie Papierkorb, Junk usw.). Als nächstes kommt das Ordnertrennzeichen. Dieses Symbol wird für Unterordner verwendet. Für einen Nachkommen des Papierkorbs würde der Name beispielsweise wie "Papierkorb / Neuer Ordner" aussehen. Nach allen Ordnern gibt der Server mit dem Tag, das wir dem Befehl zugewiesen haben, und der Ausführungszeit dieses Befehls OK an uns zurück.  

Ordnerauswahl


Weiter müssen wir gemäß dem Schema einen Ordner auswählen, aus dem wir unsere Nachrichten straffen werden. Dies erfolgt mit dem Befehl SELECT.

4 SELECT INBOX
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded $MDNSent)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded $MDNSent \*)] Flags permitted.
* 16337 EXISTS
* 2 RECENT
* OK [UNSEEN 6037] First unseen.
* OK [UIDVALIDITY 1532079879] UIDs valid
* OK [UIDNEXT 17412] Predicted next UID
* OK [HIGHESTMODSEQ 21503] Highest
4 OK [READ-WRITE] Select completed (0.015 + 0.000 + 0.014 secs).

Wenn Sie einen Ordner auswählen, werden alle Informationen darüber zurückgegeben. Lass uns in Ordnung gehen.

  • Antworten Sie mit Flags, die im Ordner für Buchstaben zulässig sind.  
  • Antworten Sie mit Flags, die der Client für immer ändern kann
  • Antworten Sie mit der Anzahl der Buchstaben im Ordner
  • Die Antwort ist mit der Anzahl der letzten Briefe, dh derjenigen, die wir zwischen den Ordnerauswahlen erhalten haben
  • Antworten Sie mit der Anzahl der ungelesenen Nachrichten

Nun, lassen Sie uns jetzt darüber nachdenken. Den Rest der Informationen brauchen wir nicht.

Briefe anfordern


Das Interessanteste ist nun die Bitte um Briefe. Hier muss man besonders bei mobilen Clients sehr vorsichtig sein. Stimmen Sie zu, es ist unwahrscheinlich, dass Sie beim Aufrufen der Anwendung Tausende von Nachrichten vom Server an Ihre Datenbank erhalten. Darüber hinaus ist es nicht sinnvoll, den gesamten Brief herunterzuladen, da es möglicherweise nicht praktikabel ist, beispielsweise eine Liste aller Briefe anzuzeigen. Um beispielsweise die Benutzerbriefe schnell anzuzeigen, werden wir nur nach einem "Umschlag" fragen. In diesem Umschlag möchten wir sehen: Absender, Empfänger, Betreff des Briefes und Versanddatum. Wir werden die ersten 10 Beiträge laden.

5 FETCH 16337:16327 (ENVELOPE)

Der Doppelpunkt zählt das Segment der Anzahl der Buchstaben auf, die wir empfangen möchten, und in Klammern, was wir aus diesen Buchstaben lesen möchten, in diesem Fall den Umschlag des Buchstabens.

Ich werde die Antwort in Kurzform geben:

* 16334 FETCH (ENVELOPE ("Sat, 07 Sep 2019 23:07:48 +0000" "Hello from Fabric.io" (("Fabric" NIL "notifier" "fabric.io")) (("Fabric" NIL "notifier" "fabric.io")) (("Fabric" NIL "notifier" "fabric.io")) ((NIL NIL "me" "me@mail")) NIL NIL NIL "<5d7438441b07c_2d872ad30967b9646405c6@answers-notifier2012.mail>"))

Es ist klar, dass nichts klar ist. Und die Sache ist, dass das Umschlagformat von RFC 2822 vorgegeben wird. Ich werde es in diesem Artikel nicht berücksichtigen. Dieser Umschlag enthält alle erforderlichen Informationen: Datum des Eingangs des Briefes, Betreff des Briefes, Absender, Empfänger und sogar die Nachrichten-ID. Seine Kunden zeigen ein Gespräch an.

Wir konnten dem Benutzer also grundlegende Informationen über den Brief anzeigen, aber was ist mit dem Körper?
Wir können sofort den gesamten Text des Briefes herunterladen, unabhängig von seiner Größe. Dies ist natürlich nicht lange, aber dennoch kostspielig über das Netzwerk und den Speicher. Dies geschieht übrigens mit demselben FETCH-Befehl. 

6 FETCH 16337:16327 (BODY[]) 

Versuchen Sie einen solchen Befehl in Ihrem Posteingang, und Sie werden verstehen, was ich mit "teuer" gemeint habe. Selbst bei 10 Nachrichten erhalten wir eine ziemlich umfangreiche Antwort mit absolut allen Informationen über den Brief. Apropos sie.

Wie oft haben Sie die Quelle des Briefes in einem Ihnen bekannten Kunden heruntergeladen, um zu sehen, wie er in seiner ursprünglichen Form aussieht? Wenn nicht, lassen Sie uns einen Testbrief herausholen. Darin habe ich ein Bild direkt zum Brief und ein Bild als Anhang hinzugefügt. Speichern Sie es im EML-Format und öffnen Sie es mit einem beliebigen Texteditor. Je nach Kunde erhalten Sie unterschiedliche Quellen für den Brief, die jedoch im Allgemeinen ähnlich sind. 

Beginnen wir mit dem E-Mail-Header:

Return-Path: <myemail>
Delivered-To:myemail
Received: from localhost (localhost [127.0.0.1])
	byimap.server.com (imap.server.com) with ESMTP id 6C2BE2A0363
	for <myemail>; Sun,  8 Sep 2019 23:41:29 +0300 (MSK)
X-Virus-Scanned: amavisd-new at imap.server.com
Received: from imap.server.com ([127.0.0.1])
	by localhost ( imap.server.com [127.0.0.1]) (amavisd-new, port 10026)
	with ESMTP id abx8HQQT_k5A for <myemail>;
	Sun,  8 Sep 2019 23:41:29 +0300 (MSK)
Mime-Version: 1.0
Date: Sun, 08 Sep 2019 20:41:28 +0000
Content-Type: multipart/mixed;
 boundary=»--=_Part_722_554093397.1567975288»
Message-ID: <9e4e3872e603eac2c20f26bb1d65548d>
From: "Me" <myemail>
Subject: Hey, Habr!
To: myemail
X-Priority: 3 (Normal)

Alle Metainformationen werden in der Kopfzeile des Briefes beschrieben, von wem, an wen, wann, Art des Nachrichteninhalts, Betreff und Priorität des Briefes. Das Grenzfeld gibt die Grenze des Buchstabens an.

Verstehe weiter, was das bedeutet.

----=_Part_722_554093397.1567975288
Content-Type: multipart/related;
 boundary=»--=_Part_583_946112260.1567975288»
----=_Part_583_946112260.1567975288
Content-Type: multipart/alternative;
 boundary=»--=_Part_881_599167713.1567975288»
----=_Part_881_599167713.1567975288
Content-Type: text/plain; charset=«utf-8»
Content-Transfer-Encoding: quoted-printable
----=_Part_881_599167713.1567975288
Content-Type: text/html; charset=«utf-8»
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE html><html><head><meta http-equiv=3D"Content-Type" content=3D"t=
ext/html; charset=3Dutf-8" /></head><body><div data-crea=3D"font-wrapper"=
 style=3D«font-family: XO Tahion; font-size: 16px; direction: ltr»> <img =
src=3D"cid:jua-uid-q1nz1guinitrcfd3-1567975257318"><br><br><div></div> <b=
r> </div></body></html>
----=_Part_881_599167713.1567975288--
----=_Part_583_946112260.1567975288
Content-Type: image/jpeg; name=«2018-09-04 22.46.36.jpg»
Content-Disposition: inline; filename=«2018-09-04 22.46.36.jpg»
Content-ID: <jua-uid-q1nz1guinitrcfd3-1567975257318>
Content-Transfer-Encoding: base64

Jede Grenze ist die übliche Grenze einer Schrift. Sie beginnen mit zwei Bindestrichen "-". Die schließende Grenze hat diese beiden Bindestriche am Ende. Es wird ausführlicher in RFC1341 beschrieben.

Dies kann als Hauptteil des Briefes bezeichnet werden. Teile des Briefes und ihre MIME-Typen werden hier beschrieben.

Informationen zu MIME-Typen
Ein MIME-Typ ist ein Medientyp, der in MIME ( Multipurpose Internet Mail Extensions) beschrieben wurde, um die Inhaltstypen in einer E-Mail-Nachricht zu beschreiben. 

  • mehrteilig / gemischt sagt uns, dass der Buchstabe eine gemischte Struktur hat, dh verschiedene Teile von Buchstaben können unterschiedliche Darstellungen dieser oder jener Informationen sein. 

  • multipart/related , , , 

  • multipart/alternative , , , text/plain text/html, . 


Wir haben hier keinen einfachen Text, daher ist es logischer, eine HTML-Darstellung zu erstellen. In dieser HTML-Präsentation gibt es nur ein Bild mit dem Parameter Content-Disposition: Inline, das heißt, es befindet sich direkt im Hauptteil des Briefes und nicht in den angehängten Dokumenten.

Der Link zu diesem Bild ist nicht ganz einfach. Es wird durch den Parameter Content-ID beschrieben, der gleich jua-uid-q1nz1guinitrcfd3-1567975257318 ist . Dies ist ein Link zum nächsten Teil des Briefes - ein Bild, das in Base-64 codiert ist. Um meine Nerven zu schonen, habe ich nicht den gesamten Base-64-Code eingefügt.

Der letzte Teil des Briefes hat das Formular 

----=_Part_722_554093397.1567975288
Content-Type: image/png; name=«2018-07-02 11.08.23 pm.png»
Content-Disposition: attachment; filename=«2018-07-02 11.08.23 pm.png»
Content-Transfer-Encoding: base64

die bereits Content-Disposition nicht inline hat, wie das Bild oben, sondern Anhang. Dieses Bild sollte nur in das Dateianhangfenster gelangen, da es übrigens auch in Base-64 codiert ist und eine große Größe hat. Hier wird klar, dass Sie nicht noch einmal den gesamten Textkörper laden sollten, wenn wir nur grundlegende Informationen anzeigen möchten. 

Zurück zum Protokoll


Nachdem Sie an den Buchstaben gearbeitet haben, müssen Sie den ausgewählten Ordner schließen und sich vom Server verabschieden. Um den Ordner zu schließen, müssen wir den Befehl CLOSE eingeben. Ja, es ist so einfach


7 CLOSE
7 OK Close completed (0.001 + 0.000 secs).

Übrigens, wenn Sie parallel mit mir mit der Konsole gearbeitet und den Artikel gelesen haben, könnte ein nicht so angenehmes Ereignis eingetreten sein, der Server könnte Ihre Verbindung durch Timeout schließen. Dies ist völlig normal und jeder Server hat sein eigenes Timeout. Wir haben beispielsweise 30 Minuten Zeit. 
Daher wird empfohlen, den NOOP-Befehl im Hintergrund auszuführen

1 NOOP
1 OK NOOP completed (0.001 + 0.000 secs).

Es macht buchstäblich nichts, aber Sie können die Verbindung ohne Zeitüberschreitung so lange beibehalten, wie wir es benötigen. Wenn Sie derzeit einen Ordner auswählen, kann NOOP als regelmäßige Anforderung für Änderungen an diesem Ordner fungieren 

1 NOOP
* 16472 EXPUNGE
* 16471 EXPUNGE
* 16472 EXISTS
* 1 RECENT
1 OK NOOP completed (0.004 + 0.000 + 0.003 secs).

Hier in der Antwort werden wir über zwei gelöschte Nachrichten informiert, eine neue und dass die Anzahl der Nachrichten in diesem Ordner 16 472 beträgt.

Ich stelle auch fest, dass Sie nur mit einem ausgewählten Ordner arbeiten können, hier gibt es keine parallele Arbeit.

Nun, am Ende schließen Sie die Sitzung mit dem Server und wir werden uns von ihm verabschieden.

8 LOGOUT
* BYE Logging out
8 OK Logout completed (0.001 + 0.000 secs).

Wir sehen die traurige, nicht getaggte BYE-Antwort, was bedeutet, dass es Zeit ist, den Job zu beenden.

Schnelle Synchronisierung mit CONDSOTORE und QRESYNC


Mit der NOOP-Operation können Sie Änderungen in einem Feld in einem ausgewählten Ordner verfolgen. Aber was ist, wenn wir herausfinden möchten, was sich in dem Ordner geändert hat, während wir mit einem anderen gearbeitet haben? Die naheliegendste Option besteht darin, alle Buchstaben im lokalen Speicher zu sortieren, unabhängig davon, ob es sich um einen Cache oder eine Datenbank handelt, und mit dem zu vergleichen, was der Server zurückgibt. Einerseits ist dies in der Tat eine Lösung, und auf einigen Servern wird es buchstäblich die einzig wahre sein. Auf der anderen Seite möchten wir Buchstaben so schnell anzeigen, wie es das Protokoll allgemein zulässt. Glücklicherweise unterstützt unser Server Protokollerweiterungen wie CONDSTORE und QRESYNC, die zu RFC7162 hinzugefügt wurden. Die erste fügt der Nachricht und dem Ordner eine spezielle 63-Bit-Nummer hinzu, die als Mod-Sequenz bezeichnet wird und mit jeder Operation an diesem Buchstaben zunimmt. Die höchste Mod-Sequenz unter allen Nachrichten wird dem Ordner hinzugefügt. Infolgedessen können wir jedes Mal, wenn Sie eine Verbindung zu einem Ordner auf einem Server herstellen, der CONDSTORE unterstützt, leicht herausfinden, ob sich etwas geändert hat oder nicht, indem wir einfach die Mod-Sequenz-Werte für den lokalen Ordner und den Server-Ordner vergleichen.

Darüber hinaus fügt diese Erweiterung zusätzliche Parameter für die STORE- und FETCH-Befehle hinzu - CHANGEDSINCE-Mod-Sequenz und UNCHANGEDSINCE-Mod-Sequenz, mit denen Sie eine Operation ausführen können, wenn die Mod-Sequenz der übertragenen Nachrichten größer bzw. kleiner als die angegebene ist. Schauen wir uns ein Beispiel an.

FETCH 17221:17241 (UID) (CHANGEDSINCE 0)
* OK [HIGHESTMODSEQ 22746] Highest
* 17222 FETCH (UID 18319 MODSEQ (22580))
* 17223 FETCH (UID 18320 MODSEQ (22601))
* 17224 FETCH (UID 18324 MODSEQ (22607))
* 17225 FETCH (UID 18325 MODSEQ (22604))
* 17226 FETCH (UID 18326 MODSEQ (22608))
* 17227 FETCH (UID 18327 MODSEQ (22614))
* 17228 FETCH (UID 18328 MODSEQ (22613))
* 17229 FETCH (UID 18336 MODSEQ (22628))
* 17230 FETCH (UID 18338 MODSEQ (22628))
* 17231 FETCH (UID 18340 MODSEQ (22628)
* 17232 FETCH (UID 18341 MODSEQ (22628))
* 17221 FETCH (UID 18318 MODSEQ (22583))

Ich habe eine Situation simuliert, in der wir in die Mailbox gegangen sind und vorher nichts davon gewusst haben, dh unsere lokale Mod-Sequenz ist 0. Wie Sie sehen, gibt der Server im Allgemeinen alle Nachrichten zurück, die sich in der Mailbox befinden, da wir zuvor nichts erhalten haben und weiß nichts über die Box. Als Antwort auf eine Anfrage nach UID-Briefen von CHANGEDSINCE enthält eine Antwort ohne Tags OK auch einen HIGHESTMODESEQ, den wir jetzt speichern, und für jede Nachricht unseren MODSEQ.

Wir werden einige Operationen mit der Mailbox ausführen : Neue Buchstaben hinzufügen, Flags ändern. Lassen Sie uns eine neue Anfrage stellen, aber mit der vorherigen Mod-Sequenz

1 fetch 17221:* (UID FLAGS) (CHANGEDSINCE 22746)
* 17267 FETCH (UID 18378 FLAGS () MODSEQ (22753))
* 17270 FETCH (UID 18381 FLAGS (\Seen) MODSEQ (22754))
* 17271 FETCH (UID 18382 FLAGS () MODSEQ (22751))
* 17273 FETCH (UID 18384 FLAGS () MODSEQ (22750))

und wir sehen bereits den Unterschied, anstatt 20 alte und neue Communities auszugeben, die gerade angekommen sind (Sternchen 17221: * bedeutet, Buchstaben von Nummer 17221 auf das Maximum zu bringen), erhalten wir Briefe, deren MODSEQ größer als die vorherige ist. Dies hilft sehr gut, einen Ordner zu synchronisieren, in dem wir uns seit einiger Zeit nicht mehr befinden, und eine Art Besetzung der geänderten Buchstaben zu erhalten, anstatt alle möglichen zu versuchen.

Es scheint viel besser zu sein? Mit QRESYNC wird der Synchronisierungsvorgang jedoch noch schneller. Sie können die MODSEQ-Parameter und die uns bekannten Nachrichten-UIDs direkt bei der Ordnerauswahl angeben. Lassen Sie uns mit einem Beispiel erklären. Zunächst muss QRESYNC mit dem Befehl ENABLE aktiviert werden. 

1 ENABLE QRESYNC
* ENABLED QRESYNC
1 OK Enabled (0.001 + 0.000 secs).
1 SELECT INBOX (QRESYNC (0 0))
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded $MDNSent)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded $MDNSent \*)] Flags permitted.
* 17271 EXISTS
* 0 RECENT
* OK [UNSEEN 17241] First unseen.
* OK [UIDVALIDITY 1532079879] UIDs valid
* OK [UIDNEXT 18385] Predicted next UID
* OK [HIGHESTMODSEQ 22754] Highest
1 OK [READ-WRITE] Select completed (0.001 + 0.000 secs).

Da wir vorher nichts über den Ordner wussten, gibt der Server nur Informationen über den Ordner an uns zurück, ohne ein Nugget seiner Änderungen. Angenommen, wir haben die ersten zwanzig Nachrichten abgefragt und uns an ihre UID und auch an HIGHESTMODESEQ erinnert. Wir verlassen den Ordner, senden uns eine Nachricht, löschen die Nachricht, ändern die Flags und kehren mit den früheren Informationen über den Ordner zurück

1 CLOSE
1 OK Close completed (0.001 + 0.000 secs).
1 SELECT INBOX (QRESYNC (1532079879 22754 18300:18385))
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded $MDNSent)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded $MDNSent \*)] Flags permitted.
* 17271 EXISTS
* 0 RECENT
* OK [UNSEEN 17241] First unseen.
* OK [UIDVALIDITY 1532079879] UIDs valid
* OK [UIDNEXT 18386] Predicted next UID
* OK [HIGHESTMODSEQ 22757] Highest
* VANISHED (EARLIER) 18380
* 17269 FETCH (UID 18383 FLAGS () MODSEQ (22757))
* 17271 FETCH (UID 18385 FLAGS () MODSEQ (22755))
1 OK [READ-WRITE] Select completed (0.001 + 0.000 secs).

Und jetzt erhalten wir bei der Auswahl eines geänderten Ordners sofort ein Nugget an Änderungen in Form einer Antwort VANISHED (EARLIER) für gelöschte Nachrichten und FETCH für hinzugefügte oder geänderte Nachrichten. Jetzt ist es noch einfacher, den Ordner zu synchronisieren, wenn der Benutzer ihn längere Zeit nicht besucht hat. Dies ist eine sehr coole Methode, wenn Sie eine Reihe von Nachrichten lokal im Cache gespeichert haben und diese nicht mit Nachrichten auf dem Server vergleichen möchten.

Der erste Parameter dieser Anforderung ist UIDVALIDITY, mit dem im Wesentlichen überprüft wird, ob sich die zuvor empfangene UID im Ordner nicht geändert hat. Dies kann passieren, wenn der Server die Sitzungs-UID für alle Nachrichten von Sitzung zu Sitzung ändert oder der Ordner gelöscht wurde und an seiner Stelle ein Ordner mit demselben Namen erstellt wurde.

Der zweite Parameter ist der uns bekannte HIGHESTMODSEQ und der letzte ist das Intervall bekannter UIDs. Sie können als Doppelpunkt geschrieben werden, wenn das Intervall kontinuierlich ist oder durch ein Komma getrennt ist.

Fazit


In meinem Beispiel bin ich auf eine Situation gestoßen, in der Unkenntnis des Themenbereichs zu einer fehlerhaften und suboptimalen Funktionsweise der Anwendung führt. Ich habe in diesem Artikel nicht alle möglichen Optionen für die Verwendung des Protokolls behandelt. Ich hoffe jedoch, dass die obigen Informationen für den nächsten Entwickler des IMAP-Clients hilfreich sind.

IMAP hat eine Menge interessanter Sachen. Befehle für die schnelle Synchronisierung sind nur der Anfang. Tatsächlich können Sie verschiedene IMAP-Befehle je nach den Funktionen des Servers weiter optimieren und die Arbeit mit E-Mails schneller, wirtschaftlicher in Bezug auf Netzwerk und Speicher und im Allgemeinen angenehmer gestalten. Aber darüber werde ich später sprechen.

All Articles