V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nice2cu
V2EX  ›  Java

邮件增量拉取

  •  
  •   nice2cu · 2023-11-20 19:43:27 +08:00 · 1484 次点击
    这是一个创建于 367 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用 pop 或 imap 协议拉取邮件,怎么实现增量拉取呢,有做过这个功能的老哥吗
    13 条回复    2023-11-22 12:46:52 +08:00
    rekulas
        1
    rekulas  
       2023-11-20 21:39:07 +08:00
    直接看库文档吧应该说明的很清楚,以前做过 go 版本的, 貌似我是倒序拉取的,不断轮询直到遇到上次的检查点说明新邮件就拉完了,imap 协议应该通用的都支持
    cp19890714
        2
    cp19890714  
       2023-11-20 22:59:22 +08:00
    有状态: 如 1 楼所说
    无状态: 建立一个文件夹, 拉取过的邮件移动到这个文件夹中.
    Shawee
        3
    Shawee  
       2023-11-20 23:28:00 +08:00
    直接拉取未读的,读完后设置为已读呢
    hedwi
        4
    hedwi  
       2023-11-20 23:30:19 +08:00
    可以根据序号 seq id 拉取 序号一般是递增的 但是序号可能会变化 或者每次拉取全量 uid 再根据 uid 拉取每一封邮件
    ipeony
        5
    ipeony  
       2023-11-21 08:17:38 +08:00
    写过一个按时间段拉取的
    kiml
        6
    kiml  
       2023-11-21 08:36:26 +08:00 via Android   ❤️ 1
    刚刚做过这个功能,它有一个拉取未读邮件列表的功能,拉取到的列表会包含邮件 id 、主题、收发件人这些信息。然后通过邮件 id 拿邮件内容,内容需要解码一下。处理完之后标记已读就行。做的时候如果是多进程跑,记得加分布式锁,不然会重复处理。去 github 搜你用的语言类库,有的
    nice2cu
        7
    nice2cu  
    OP
       2023-11-21 19:05:40 +08:00
    @hedwi 你这个效率会很差的
    nice2cu
        8
    nice2cu  
    OP
       2023-11-21 19:08:30 +08:00
    @kiml 佬,我现在是根据接收时间去扫描的,扫了一次,记录下同步时间,下次从这个时间继续扫描。。我是多消费者扫的,库里加了 messageid 唯一索引。。。。
    Message[] searchResults = inbox.search(messageToolHelp.getAndDateSearchTerm(startTime, endTime));
    这种效率算不算好,就有点疑惑,一般是不是这样实现的
    nice2cu
        9
    nice2cu  
    OP
       2023-11-21 19:09:50 +08:00
    @hedwi 我查过资料是说 uid 会重新分配在删除一封邮件时。。用 uid 去增量拉的会有问题吧
    hedwi
        10
    hedwi  
       2023-11-21 22:42:21 +08:00
    @nice2cu #9 uid 是每个文件夹单独分配的 不会冲突 可以单独获取 uid 列表而不获取邮件 header 和内容 uid 是 imap 服务器生成的 效率不会差吧
    nice2cu
        11
    nice2cu  
    OP
       2023-11-22 09:11:27 +08:00
    @hedwi 好的 那如果是 pop 呢 没有 uid 那用啥
    ttvast
        12
    ttvast  
       2023-11-22 10:46:18 +08:00
    GPT 回复
    pop3 协议获取邮件列表的命令是什么,返回的邮件列表格式是什么
    ChatGPT
    POP3 ( Post Office Protocol version 3 )协议用于从邮件服务器获取电子邮件。获取邮件列表的主要命令有两个:

    LIST 命令:这个命令用于获取邮箱中所有邮件的列表。它会返回每封邮件的唯一标识符(通常是序号)和大小。命令格式为:

    Copy code
    LIST
    服务器对此命令的响应通常是多行的,每行包含一个邮件的序号和该邮件的大小(以字节为单位)。例如:

    diff
    Copy code
    +OK 2 messages (320 octets)
    1 120
    2 200
    .
    上面的响应表示邮箱中有两封邮件,第一封邮件的大小为 120 字节,第二封为 200 字节。响应以单独的一行点号(.)结束。

    UIDL 命令:这个命令也用于获取邮件列表,但它返回的是每封邮件的唯一标识符( UIDL ),这对于客户端来识别邮件特别有用。命令格式为:

    objectivec
    Copy code
    UIDL
    服务器对此命令的响应类似于 LIST 命令,但每行包含邮件的序号和该邮件的唯一标识符。例如:

    diff
    Copy code
    +OK
    1 whqtswO00WBw418f9t5JxYwZ
    2 QhdPYR:00WBw1Ph7x7
    .
    这里,每个邮件旁边的字符串是它的唯一标识符。

    这些命令允许邮件客户端查看服务器上的邮件,决定哪些邮件需要下载或删除。
    kiml
        13
    kiml  
       2023-11-22 12:46:52 +08:00 via Android
    @nice2cu 佬,我是菜鸡。
    个人认为你这个方案效率是没问题的。但是多消费者去拉取的时候,你应该是处理完才写时间戳吧?
    这里面会有时间差问题。就算你进程一开始就写处理时间戳,还是有概率会时间交叉。
    而且,如果说你这个消费者任务写完时间戳 g 掉了咋办,这不就丢数据了吗?
    自认为可以优化的地方,消费进程开始时写时间戳,然后写时间戳这个事件加一个分布式锁,确保只有一个进程在写时间戳,拿到锁才能写。
    至于丢数据的问题就需要你业务逻辑去确保了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   971 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 21:39 · PVG 05:39 · LAX 13:39 · JFK 16:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.