1

我正在编写一个 C# 程序,该程序使用 POP3 监视专用的 Gmail 帐户以接收专门的命令电子邮件并做出适当的反应。

为了获得最大的可靠性,我将在全国的多台计算机上运行这个程序。我目前有一个竞争条件,程序的两个实例可以在其中一个删除相同的消息之前读取它,导致消息被处理两次。

如何确保每个命令只处理一次?

Gmail 的 POP3 访问过去只为每封邮件提供一次(使 RETR 和 DELE 成为单个原子操作),但我无法再重现这种行为。

计算机之间唯一的通信方法是 SQL Server 和 HTTP 服务器(由我控制)。

4

2 回答 2

1

我想到的一个选项是使用 POP3 的 UIDL 命令,并在 SQL Server 中有一个表,其中包含已处理的唯一 UIDL 列。

然后,在下载每条消息之前,守护程序会将 UIDL 插入表中,如果出现错误,则跳过该消息。(我假设 SQL Server 的 INSERT 命令是原子操作)。

于 2009-05-27T00:57:29.297 回答
0

首先我必须承认我不知道 POP3 支持什么命令,但是......如果你可以做一个明确的'DELE'并且如果消息不再存在则得到一个错误,那么我会说:

  • 撤回消息
  • 删除消息
  • 仅在 DELE 成功时处理

编辑:

阅读 RFC1939 后,这种方法应该可行;来自 RFC:

DELE msg

     Arguments:
         a message-number (required) which may NOT refer to a
         message marked as deleted

     Restrictions:
         may only be given in the TRANSACTION state

     Discussion:
         The POP3 server marks the message as deleted.  Any future
         reference to the message-number associated with the message
         in a POP3 command generates an error.  The POP3 server does
         not actually delete the message until the POP3 session
         enters the UPDATE state.

     Possible Responses:
         +OK message deleted
         -ERR no such message

     Examples:
         C: DELE 1
         S: +OK message 1 deleted
            ...
         C: DELE 2
         S: -ERR message 2 already deleted

这当然是假设 Gmail 实现实际上遵守 RFC。

于 2009-05-27T01:21:14.363 回答