因此,我的任务是设置 MSMQ,以便如果我们的邮件服务器出现故障(这似乎经常发生),消息只会在队列中结束,并在它们恢复时被传递。话虽如此,我不得不说我对此知之甚少,除了我在过去 24 小时内学到的东西,但我相信我知道的足够多,可以采取正确的方法,但我想问社区中的某个人,因为有些困惑在我的同事中,我们在 WCF 应用程序中给出了一些现有设置。
目前我们有一些使用 msmq 作为端点协议的服务。端点看起来像这样
<endpoint address="net.msmq://localhost/private/Publisher"
behaviorConfiguration="BatchBehaviour"
binding="netMsmqBinding"
bindingConfiguration="MSMQNoSecurity"
contract="HumanArc.Compass.Shared.Publisher.Interfaces.Service.IPublisherSubscriber"
name="PublishSubscriber"/>
这当然可以让客户端进行服务调用,如果由于某种原因服务没有启动,它将确保当服务恢复时调用将被处理。我认为它不会做的是,如果您的服务方法中有以下内容。
try
{
smtp.Send(mail);
return true;
}
catch (System.Net.Mail.SmtpFailedRecipientException ex)
{
throw new Exception("User Credentials for sending the Email are Invalid",ex);
}
catch (System.Net.Mail.SmtpException smtpEx)
{
throw new Exception(string.Format("Application encountered a problem send a mail message to {0} ", smtpHostName),smtpEx);
}
WCF 不会以某种方式重试并再次发送消息,我对这个假设是否正确?
我认为我们应该拥有如下所示的东西来代替上面对 smtp.send() 的调用。(来自http://www.bowu.org/it/microsoft/net/email-asp-net-mvc-msmq-2.html)
string queuePath = @".\private$\WebsiteEmails";
MessageQueue msgQ;
//if this queue doesn't exist we will create it
if(!MessageQueue.Exists(queuePath))
MessageQueue.Create(queuePath);
msgQ = new MessageQueue(queuePath);
msgQ.Formatter = new BinaryMessageFormatter();
msgQ.Send(msg);
然后在服务启动的某个地方(我还不确定在哪里)我们设置了一个事件处理程序,它将实际调用 SmtpClient 对象上的 send()。像这样的东西
msgQ.ReceiveCompleted += new ReceiveCompletedEventHandler(msgQ_ReceiveCompleted)
所以总而言之,我的第一个问题是哪种方式更好?创建一个使用 net:msmq 作为协议的服务,或者只是更改电子邮件方法以将消息放入队列并为其设置处理程序?下一个问题,如果我关于更改调用 SmtpClient.Send() 的方法的假设是正确的,那么我应该在程序的哪个位置连接 ReceiveCompleted?Out WCF 服务托管在 Windows 服务中,这意味着实际上调用了 ServiceBase.Run(servicesToRun)。有地方可以把它连线吗?我对 WCF 的体验是使用更简单的 IIS 托管服务,所以我不能 100% 确定。
谢谢 - 我意识到这是一个很长的问题,但我一直在努力研究它,并且有很多信息,我似乎无法找到一个明确的解释,说明以一种方式做事与另一种做事的好处。