簡體   English   中英

使用 imap_tools(或 imaplib),如何通過重復獲取整個 imap 數據庫來同步 imap 更改而不是輪詢?

[英]With imap_tools (or imaplib), how do I sync imap changes instead of polling by repeatedly fetching the entire imap database?

由於周圍有幾個類似的問題,我想非常准確。

編輯:讓我們專注於對從一個文件夾移動到另一個文件夾的任何 email 消息進行動態反應。

典型的 imap 客戶端應用程序僅獲取自上次同步以來 imap 數據庫中的更改。 如果您的 email 客戶端每次運行時都必須獲取每個 email,那將需要很長時間。

不幸的是,我的 imap_tools 應用程序每次運行時都必須獲取(僅標題)整個 imap 數據庫。 為了動態檢測變化,我必須反復輪詢整組消息。 顯然,這不是一個合理的設計。

imap_tools(或底層 imaplib)是否提供同步機制?

不是使用“seen”標志。 那是用於指示人是否已經閱讀了消息,並且也不是特定於特定客戶端的。

依靠 uid 並不完全是因為我想檢測用戶是否已刪除或將郵件從一個文件夾移動到另一個文件夾。

你可以:

  • 對限制數據集使用搜索參數:date_gte、date_lt、new...
  • 如果您存儲某些內容,請依賴標頭中的 message-id
  • 使用mailbox.move作為可靠的“標記”消息而不是標志
  • 計算味精 hash

一切都取決於你的任務。

據我所知,IMAP 中沒有“同步”,有 IDLE,但 imap_tools 做不到。

IMAP 的核心是一種舊的且效率不高的協議,因為設計並不專注於同步。 Kundrát稱其為Cache Filing Protocol :服務器是事實的唯一來源,客戶端的工作是向用戶顯示此內容,並且通常盡可能多地緩存此內容。

在基線 IMAP 中,這通常意味着連接到服務器,並詢問和緩存客戶端希望顯示的盡可能多的信息。 消息、標題、標志、可能是正文、可能是附件的數量。

它還假設客戶端在使用時具有大部分穩定的網絡連接,大多數桌面模式客戶端都是如此。 同步所有數據后,服務器可以主動向您unsolicited responses :當有EXISTS進入時存在; 更新EXPUNGESTORE ,刪除消息時刪除。 除非響應允許的用戶命令,否則服務器通常不會發送這些。 老客戶經常使用NOOP ,或者可能為此使用CHECK

如果您失去連接,客戶端將重新連接並刷新其緩存。 由於關於消息的唯一可變因素是它們的存在和標志,這通常相當快:客戶端通常會為所有消息請求所有標志。 從那里它可以快速更新其緩存。 應用標志。 獲取它發現的新 UID 的標頭,刪除它沒有收到的 UID 的緩存版本。

當一個文件夾有數萬條消息時,這確實開始崩潰,您會發現客戶端此時在某些服務器上的啟動/同步速度開始非常慢,並且開始使用相當多的數據。

IMAP 作為一種協議不能跨文件夾跟蹤郵件。 每個文件夾的 state 是完全獨立的。 如果它被移動,則相當於從一個文件夾中刪除並添加到另一個文件夾。 桌面客戶端通常會維護一個連接池,以便一次查看多個文件夾。 您可以將啟發式方法應用於緩存消息以嘗試檢測文件夾移動(例如,標題和元數據的選擇),但它並不完美。


如您所見,一旦您的郵箱超過幾百條消息,其中的大部分效率都非常低,因此有很多擴展可以提高緩存效率。

UIDPLUS (RFC4315) 幾乎無處不在。 這要求服務器在更多命令中支持 UID,並且幾乎是任何緩存模式客戶端都需要的,因為在涉及刪除時消息序列號是不可靠的。

IDLE (RFC 2177) 相當普遍,但並非無處不在。 客戶端可以發出一個IDLE命令,這會告訴服務器它隨時准備好接受那些未經請求的更新。 這意味着客戶端不必每隔幾分鍾使用NOOP命令輪詢一次。

CONDSTORE (RFC 4551) 在大多數 unix 類型的服務器和一些商業服務器上。 除其他外,它將序列號與標志更改相關聯。 這允許標志重新同步步驟僅從它知道的最新序列號中獲取更改。 但是,它無助於檢測已刪除的消息,並且仍然需要UID SEARCH ALL才能在斷開連接后找到這些消息。

QRESYNC (RFC5162) 為已刪除消息提供重新同步數據。 不幸的是,這是一個非常罕見的擴展,在大型商業服務器上幾乎不存在。

NOTIFY (RFC5465) 幾乎無處可去。 它應該像一個超級IDLE,可以同時監控多個郵箱。

Gmail Extensions當然是 Gmail 特定的。 除其他外,它將永久標識符與每條消息(X-GM-MSGID)相關聯,這確實允許跨文件夾可靠地跟蹤它。 它還提供“所有郵件”文件夾和標簽,這意味着您可以通過同步所有郵件文件夾來同步整個帳戶。 與其他服務器一樣,當收到數萬條消息時,這確實開始導致帶寬效率低下。


根據我參與開發幾個強調帶寬效率和響應能力的移動 email 客戶端的經驗,即使在處理 IMAP 的所有問題時,客戶端也會顯得非常響應。 IDLE可用於嘗試保持收件箱同步。 如果你不能這樣做,你可以通過只保持最近一周的消息完全同步來隱藏很多卡頓,並減少同步 rest 的頻率(UID SEARCH SINCE 在這里很有幫助)。 用戶通常只查看收件箱的末尾,並且通常只關心收到的新消息。

一般來說,鏡像消息的移動實際上只是被檢測為刪除和添加,它只是互聯網連接和服務器非常快,而且需要幾百毫秒的東西對用戶來說可能是即時的。 如果發生任何優化,它是啟發式的。 我認為 Thunderbird 可以有一個可以打開的協議日志。 如果你真的很好奇它在做什么,打開它並移動一條消息,看看它做了什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM