如何处理SMTP超时

时间:2017-09-13 11:35:28

标签: error-handling smtp exchange-server connection-timeout retrypolicy

我使用C#编写的客户端应用程序向公司交换服务器发送批量电子邮件。

客户端应用程序超时(不是服务器)可能会发生,而且确实发生了。 由于无法知道服务器是否完成了请求,如何处理此案例的重试?

没有涉及可用于避免重复的ID。 设置长时间超时甚至无限超时都不是一个好的策略。

我正在使用指数退避算法进行重试。在这种情况下,它应该只发送一个副本,因为它将在下次等待更长时间。

我认为没有子弹教授解决方案。无论如何,因为它是第一个这类项目,我需要检查一下是否有人有我想念的解决方案。

更新: 交换正在进行中继。我正在使用SmtpClient发送电子邮件。 问题是服务器可以发送250 Ok消息,但接收者永远不会得到它,然后再试一次。这是我在这篇文章中试图解决的唯一问题。

在Rest服务中,推荐的方法是使用并发错误。如果客户发布了一些东西并且得到了#34; 409 - 冲突"状态,表示消息已存储在服务器上。但是要发生这种情况,要成为客户端创建的消息的密钥,并且是消息的一部分。 SMTP似乎没有一种可以防止这种情况的机制。

2 个答案:

答案 0 :(得分:0)

通常情况下,如果SMTP服务器在使用标准SMTP时接受了电子邮件,则会向您提供信息。以下是telnet的一个例子:

enter image description here enter image description here

因此,您的应用程序只需要在此处跟踪响应,如果发生超时,您不需要继续处理所有电子邮件,并且需要在停止的位置进行检索。顺便说一下,你的应用程序每次都应该检查响应,因为发送者或接收者不被接受......

RFC 5321中提到了这一点(您可以在该文档中滚动):

  

当接收方-SMTP接受一封邮件时(通过发送“250   确定“响应DATA的消息”,它正在接受责任   用于传递或转发消息。必须采取这一点   责任认真。它绝不能丢失消息   轻浮的原因,比如因为主机后来崩溃或   由于可预测的资源短缺。 [...]成功接收并存储文本结束后,SMTP接收方发送“250 OK”回复。

当您发送电子邮件时,我认为第4.5.4.1节。如果您没有使用某种处理RFC符合的外发电子邮件的框架,那么这可能很重要。

示例:您的客户端正在生成电子邮件,但在正文提交期间(电子邮件传输的最后一部分),连接已丢弃。然后,服务器不允许继续发送电子邮件。从技术上讲,他可能得到了所有的信息,但是RFC没有允许他发送信息,因为客户端已超时并且没有完成整个过程。

<强>更新 最好的方法是使用C# SmtpClient method,然后检查smtpStatusCode确定(=“电子邮件已成功发送到SMTP服务。”),您可以在telnet示例中看到。这种方法在这里没有做任何其他事情(技术上)。该方法也符合RFC 5321,因此您无需重新发明smtp发送轮。如果你没有得到OK,那么同时可能发生了一些事情,你需要检查结果,然后执行重新发送(或者如果错误消息说电子邮件地址无效或需要放弃)类似的东西,以避免无限循环)。

答案 1 :(得分:0)

另一种可能的选择可能是涉及Microsoft Exchange Webservices。您也可以使用它们发送电子邮件。 here的示例:

// Create an email message and identify the Exchange service.
EmailMessage message = new EmailMessage(service);

// Add properties to the email message.
message.Subject = "Interesting";
message.Body = "The merger is finalized.";
message.ToRecipients.Add("user1@contoso.com");

// Send the email message and save a copy.
message.SendAndSaveCopy();

他们也给你回复:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="14" 
               MinorVersion="0" 
               MajorBuildNumber="639" 
               MinorBuildNumber="20" 
               Version="Exchange2010" 
               xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" 
               xmlns="http://schemas.microsoft.com/exchange/services/2006/types" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xm=""lns:xsd="http://www.w3.org/2001/XMLSchema" />
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <m:CreateItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" 
               xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:CreateItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:Items />
        </m:CreateItemResponseMessage>
      </m:ResponseMessages>
    </m:CreateItemResponse>
  </s:Body>
</s:Envelope>