Delphi ISAPI连接内的TidSMPT在一段时间后关闭
我们所看到的情况: 我有一个ISAPI应用程序,它使用TidMessage发送电子邮件。它运行在我们的实时网络服务器上,发送电子邮件在相当长一段时间内没有问题。然后它会突然停止工作,我们开始看到一个错误,表示连接正常关闭。我所要做的就是重新启动IIS,或者重新启动服务器,一切都会重新开始工作,没有问题 我们正在做的是: ISAPI在第一次需要时创建一个TIDSSMTP和TIdSSLIOHandlerSocketOpenSSL。当系统卸载时,这些实例是空闲的。当ISS卸载ISAPI时(它可能没有卸载),或者当我们重新启动、回收、重新启动iis时 然后,每次我们需要发送电子邮件时,我们都会创建一条TidMessage和任何其他需要的对象。然后我们会在邮件发送后释放他们 我的理论是: 我记得几年前,我在一个旧的NT机箱上处理了一个类似的问题,问题是系统的管道用完了,然后我们会重新启动,所有这些都会再工作几个月 问题: 我想知道是否有人知道这可能是什么原因? 我们能用光管道吗,或者类似的东西 我们的发送电子邮件代码:Delphi ISAPI连接内的TidSMPT在一段时间后关闭,delphi,smtp,indy,delphi-xe7,isapi,Delphi,Smtp,Indy,Delphi Xe7,Isapi,我们所看到的情况: 我有一个ISAPI应用程序,它使用TidMessage发送电子邮件。它运行在我们的实时网络服务器上,发送电子邮件在相当长一段时间内没有问题。然后它会突然停止工作,我们开始看到一个错误,表示连接正常关闭。我所要做的就是重新启动IIS,或者重新启动服务器,一切都会重新开始工作,没有问题 我们正在做的是: ISAPI在第一次需要时创建一个TIDSSMTP和TIdSSLIOHandlerSocketOpenSSL。当系统卸载时,这些实例是空闲的。当ISS卸载ISAPI时(它可能没有卸
procedure TSendMailEngine.sendEmail(
const recipient, cc, replyTo, subject: string;
const plainTextList, attachmentList, htmlTextList: TStrings);
procedure AddMailSection(parts: TIdMessageParts; const section, contentType: string; const parentPart: integer); overload;
var
msgPart: TIdText;
begin
msgPart := TIdText.Create(parts, nil);
msgPart.Body.Text := section;
msgPart.ContentType := contentType;
msgPart.ParentPart := parentPart; // set to 0 if hasHtml and hasPlainText and hasAttachments, otherwise it defaults to -1
end;
procedure AddMailSection(eMailMessage: TIdMessage; const section, contentType: string); overload;
begin
eMailMessage.Body.Text := section;
eMailMessage.ContentType := contentType;
end;
procedure AddAttachments(parts: TIdMessageParts; attachments: TStrings);
var
cntr: Integer;
begin
for cntr := 0 to attachments.Count - 1 do
if FileExists(attachments[cntr]) then
TIdAttachmentFile.Create(parts, attachments[cntr]).FileName := ExtractFileName(attachments[cntr]);
end;
var
hasPlainText,
hasHtml,
hasAttachments: boolean;
parentPart: Integer;
eMailMessage: TIdMessage;
//contentIndex: Integer;
begin
parentPart := -1;
eMailMessage := TIdMessage.Create;
try
InitMessage(eMailMessage); // adds date, encoding, from info, etc
SetMessageHeader(eMailMessage, recipient, cc, replyTo, subject);
hasPlainText := Assigned(plainTextList ) and (plainTextList.Count > 0);
hasAttachments := Assigned(attachmentList) and (attachmentList.Count > 0);
hasHtml := Assigned(htmlTextList ) and (htmlTextList.Count > 0);
if hasPlainText and not(hasHtml or hasAttachments) then
AddMailSection(eMailMessage, plainTextList.Text, 'text/plain') // only a text body
else if hasHtml and not(hasPlainText or hasAttachments) then
AddMailSection(eMailMessage, htmlTextList.Text, 'text/html') // only an html body
else // mixed message type
begin
eMailMessage.ContentType := 'multipart/alternative';
if hasPlainText and hasAttachments and hasHtml then
begin
parentPart := 0;
TIdText.Create(eMailMessage.MessageParts, nil).ContentType := 'multipart/alternative';
end;
if hasPlainText then
AddMailSection(eMailMessage.MessageParts, plainTextList.Text, 'text/plain', parentPart);
if hasHtml then
AddMailSection(eMailMessage.MessageParts, htmlTextList.Text, 'text/html', parentPart);
if hasAttachments then
begin
AddAttachments(eMailMessage.MessageParts, attachmentList);
eMailMessage.Encoding := meMIME;
eMailMessage.ContentType := 'multipart/mixed';
end;
end;
Send(eMailMessage);
finally
FreeAndNil(eMailMessage);
end;
end;
编辑:
对Send的调用执行连接、身份验证、发送和断开连接:
procedure TSendMailEngine.Send(eMailMessage: TIdMessage);
begin
try
if not fSMTP.Connected then
fSMTP.Connect;
if fSMTP.Connected then
begin
if fSMTP.Authenticate then
fSMTP.Send(eMailMessage);
fSMTP.Disconnect;
end;
except
// there will be an exception if the sendFile is cancelled
// we want to wait until it completes before emailing the config file
on goodE: EIdConnClosedGracefully do
fSMTP.Disconnect;//nothing
//on another exception just let it rise up
end;
end;
您是否在两封电子邮件之间长时间保持与SMTP服务器的SMTP连接?如果是这样的话,那么SMTP就不是为此而设计的,根据RFC 5321第4.5.3.2.7节,服务器或防火墙可能会在空闲一段时间后断开您的连接,通常长达5分钟。您必须定期发送其他SMTP命令以使其保持活动状态。SMTP中没有类似心跳信号的命令。否则,如果发送电子邮件导致关闭正常错误,只需重新连接并重试电子邮件即可。@RemyLebeau此代码正在间歇性调用,我们的负载不是很重。每天只有几封电子邮件。据此,最后发送电子邮件前的最后一行;调用一个函数,该函数在内部调用connect、authenticate、send,然后disconnect。。。在不查看实际TCP通信量的情况下,将该代码添加到我的问题中,我只能假设1服务器不喜欢它正在接收的电子邮件数据,因此它立即关闭了连接,或者2在发送过程中发生了一些其他异常,导致TIdSMTP在内部调用Disconnect。您是否使用SSL/TLS?然后在您再次调用Connect之前,它会在下一个套接字操作中引发closed gracefully错误。