关于从客户端可能未连接到互联网的 2 层应用程序发送电子邮件通知的建议
我必须向客户端服务器应用程序添加电子邮件通知。
当用户在客户端 UI 上执行某些特定操作时,会发生通知。
如果我有一个中间层或在服务器上运行的服务,我可以想象如何做到这一点:
1)我只需创建一个带有“待处理通知”的数据库表
2)当用户执行生成通知的操作时,我将记录添加到表
3)服务器端我会不断尝试发送这些邮件,并在发送成功后将它们从表中删除
现在我现在不能这样做,我计划稍后添加服务,但现在我必须快速进行肮脏的方式。
所以我想以某种方式实现这样的事情:
1)当客户端发生值得通知的事件时,同一个客户端(我的exe)尝试发送通知,失败时它将在“待处理”中记录通知通知”表(失败可能是因为缺乏互联网连接或任何其他问题)
2)我添加了一个计时器,该计时器可以在任何客户端计算机上工作以检查待处理的通知。如果有任何客户端将尝试发送电子邮件(使用事务:我将一个字段标记为“TrryngToSendFromClientX”,如果失败,我将将该字段重置为 NULL)
我认为这种方法可行,它有明显的限制(如果发生故障后没有人登录系统,则不会发送任何通知 - 如果服务“关闭”,情况也是如此)。但您能否评论一下这种方法并提出更好的方法?
附加说明(为了更好地理解该场景):
a) 注意:所有通知均从同一电子邮件帐户发送。
b) 我不需要跟踪谁发送了电子邮件。
c) 现在创建服务的问题是,它基本上会使部署变得非常复杂,并且我需要创建用于监视服务状态的工具。我将来会做但不是现在的事情,将来我计划向服务添加更多功能(不仅仅是发送通知),因此在这种情况下,创建它更有意义。
d) 我将使用 Indy 组件和 SMTP 服务器发送电子邮件。
I have to add e-mail notifications to a client server application.
Notifications happen as the user do some particular action on the client UI.
If I had a middle tier or a service running at server I can imagine how to do it:
1) I simply create a DB tables with "pending notifications"
2) as a user does an action that generates a notification I add a record to the table
3) serverside I would continuously try to send those mails and removing them from the table once sending is succesful
Now I cannot do this now, I have a plan to add a service later on, but for now I must go the quick and dirty way.
So somehow what I was thinking to is to implement something like this:
1) as a notify-worth event occurs at client, the same client (my exe) tries to send the notification, upon failure it will log the notification in the "pending notifications" table (failure can be becuase lack of internet connection or any other problem)
2) I add a Timer that will work from any client machine to check for pending notifications. If there are any the client will try to send the e-mail (using a transaction: I will mark a field as "TryngToSendFromClientX" and in case of failure I will reset that field to NULL)
I think this approach would work, it has obvious limitations (if after failure no one logs into the system, no notification will be sent - same would be if service goes "down"). But can you comment on this approach and suggest a better one?
Additional notes (to better understand the scenario):
a) Note: all notifications are sent from the same e-mail account.
b) I don't need to keep track of who sent the e-mail.
c) the problem of creating the service now is that it will basically complicate significantly deployment and I need to create tools for monitoring the status of the service. Something that I will do in future but not now, in future I have plan to add more functionality (not only sending notifications) to the service, so in that case it makes more sense to create it.
d) I will send e-mails by using Indy components and SMTP server.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您现在不愿意创建该服务,我认为您将陷入您所描述的场景中。不过,您可以采取一些措施来避免在仍有待处理消息的情况下不再有用户启动客户端的问题。
您可以添加一个命令行实用程序(或 bepe4711 建议的命令行参数),该实用程序将仅检查待处理的消息并尝试发送它们。
将此命令行实用程序添加到注册表中的 StartUp 文件夹或 Run 项。这样,即使用户没有启动您的应用程序,消息至少会在计算机重新启动时发送。
添加计划任务以每天至少运行此实用程序一次。计划任务可以通过代码或安装程序添加。
如果您同时执行这两项操作,您只需担心不再启动计算机的用户的待处理消息。
If you are not willing to create the service now, I think you are stuck with the scenario you describe. There are some things though you could do to circumvent the problem of no user firing up the client anymore while there are still pending messages.
You could add a commandline utility (or commandline parameter as bepe4711 suggested) that will only check for pending messages and try to send them.
Add this commandline utility to the StartUp folder or Run key in the registry. This way messages will at least get sent when the computer restarts, even if the user does not fire up the your app.
Add a scheduled task to run this utility at least once every day. The scheduled task can be added by code or by your installer.
If you do both, you will only have to worry about pending messages of users that never start their computer again.
也许您可以向客户端添加一个参数,使其仅查看待处理的通知并发送它们。此后它可以自行终止。它就像某种服务一样。
然后在服务器上安装客户端并每 x 分钟启动一次。
Perhaps you can add a parameter to your client which causes it to just look at the pending notifications and send them. After this it can terminate itself. It will just act like some kind of service.
Then you install the client on the server and start it every x minutes.
我做的事情与你描述的方法非常相似。我需要调用网络服务,而不是发送电子邮件。我的应用程序安装在多台笔记本电脑上,它们通常未连接到任何网络。
当我的应用程序引发异常时,我会收集各种信息,包括用户评论和屏幕截图。然后我尝试将其发送到我们的网络服务。如果碰巧网络服务不可用。 (即未连接到互联网或 Web 服务已关闭)我将结果写入磁盘上用户配置文件 (App_Data) 目录中的 XML 文件。
一个主要区别是我不会轮询来检查服务器是否已启动。我尝试在应用程序启动时再次发送它们。
I do something very similar to the approach you describe. Instead of sending emails I need to call a web service. My application is installed on several laptops and they are commonly not connected to any network.
When my application raises an exception I collect various bits of information including user comments and screen shots. Then I attempt to send this to our web service. If by chance the web service is not available. (i.e. not connected to the internet or web service is down) I write the results to an XML file on disk in the User Profile (App_Data) directory.
The one major difference is I don't poll to check to see if the server is up. I attempt to send them again on the startup of the application.
如果两个系统都在 Windows 上运行,请查看 MS Message Queue。它旨在向并非始终在线的系统发送通知。我在.Net中做到了,已经实现了易于使用的类。不确定德尔福。
If both Systems are running on Windows, have a look at MS Message Queue. It is designed to send notifications to systems, which are not allways online. I did it in .Net, there are already easy to use classes implemented. Not sure about Delphi.
最新版本的 Windows 更多地使用了 Windows 任务计划程序,现在可以根据事件(即当网卡连接时...)触发任务。您可以编写一个单独的实用程序来尝试发送挂起的通知,即使没有人登录。
Latest version of Windows uses much more the Windows Task Scheduler, and now task can be fired on event (i.e. when a network card gets connected...). You could write a separate utility that tries to send pending notification, even if noone is logged in.