Indy IMAP客户端(Delphi 2009)如何发送电子邮件到达通知?

4
我正在开发一个守护程序应用,该应用将电子邮件收件箱作为其输入队列。响应时间应尽可能高,同时保持服务器开销最小,因此轮询电子邮件收件箱是不可行的。由于IMAP协议使新电子邮件通知成为可能,因此这对于该应用程序来说是理想的。
然而,当我尝试在我的Delphi/Indy应用程序中实现此机制时,遇到了麻烦。TIdIMAP4工作得很好(除了一些与Unicode无关的问题),但我找不到实现通知的方法。
这应该是一个简单的GIYF问题,但由于某种未知的原因,我在搜索在线时找不到任何有关Indy组件的相关信息。
深表感激解决方案或替代方法。
编辑:由于Indy显然不支持异步电子邮件通知,是否有人知道什么免费的Delphi组件可以实现这一点。
4个回答

4

TIdIMAP4不支持接收异步通知,例如新邮件通知。这需要将TIdIMAP4的实现更改为类似于TIdTelnet使用的多线程模型,但由于TIdIMAP4当前的阻塞命令/响应模型,所以更加复杂。目前,您必须定期轮询收件箱。


2
为什么不将应用程序作为smtp服务器,而不是客户端。
这样一来,当电子邮件直接发往您的应用程序时,您可以直接收到通知,而不必拉取新的电子邮件。
有一些缺点,即如果您的应用程序关闭,则电子邮件不会排队,尽管我相信ms exchange或postfix等可以很好地与其配合工作。

0

好的。这是另一种解决方案。假设您没有使用电子邮件的原因(例如,您的信息通过电子邮件来自外部来源),那么我建议使用数据库表作为创建输入队列的更为直接的方式。

只需定期轮询数据库即可。这比轮询电子邮件收件箱要快得多,并且比您认为的要快得多。轮询数据库非常快速,您可以轻松地每分钟轮询数百次数据库表,对性能几乎没有任何明显影响。

只需创建一个表来存储您的Q项目,并添加一个额外字段,您可以在其中存储时间戳或标志,表示此q项目已处理,然后只需从堆栈中取出下一个未处理的项目即可。

例如 mssql

select Top 1 * from tbl_MyQ where AlreadyHandled = 0 

MySQL

select  * from tbl_MyQ where AlreadyHandled = 0 Limit 1

那么

update tbl_MyQ Set AlreadyHandled = 1 where QueueID = #ItemIDRetrieved#

数据库很快,如果你担心的话可以进行测试。而且它们比IMAP事件和电子邮件收件箱简单得多。


1
我们一直在考虑这个问题,但由于输入最初来自各种人类用户的电子邮件形式,因此数据库将是一个不必要的中间步骤。 - user267885
1
还有一些数据库也实现了队列(Oracle是其中之一)。它们会处理并发性问题(你的代码不会,两个进程可能在一个进程处理完记录之前获取相同的记录)。此外,还有一些数据库可以向客户端触发事件(同样,Oracle也可以),而无需持续轮询某个表。 当然,也有纯消息队列。 - user160694

0
如果电子邮件收件箱(IMAP)是你的架构中的基本要求,且没有可用的IMAP客户端,那么我建议你尝试使用其他语言(如C、C#或Java)编写具有异步通知功能的IMAP客户端,以实现“代理”或网关,从而在新邮件到达时触发你的Delphi后台应用程序。
Delphi后台应用程序可以使用简单的套接字协议或http接收消息(TIdHTTPServer、TIdTCPClient)。
如果Indy库的学习曲线太陡峭,你可以使用免费开源的Ararat Synapse TCP/IP库编写一个原型,在我的Delphi 2009应用程序中它的表现非常好(除了编译器会抱怨一些字符串/ansi转换问题)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接