Windows Azure Cloud Service (29) 在Windows Azure发送邮件(下)

简介:

  Windows Azure Platform 系列文章目录

 

  前2章我们已经介绍了Windows Azure发送邮件的两种方法,分别是使用on-premise的Email Forward Service和Exchange Server。

  现在我们介绍第三种方法:使用第三方SMTP服务

  源代码您可以在这里下载,有三点我们需要了解: 

  1. 在Windows Azure应用程序里,我们可以使用第三方服务(SendGrid)来实现发送邮件的功能。
  2. 我们可以使用worker role的input endpoint (终结点),通过端口号25来监听SMTP流量
  3. 我们可以使用CDN endpoit,自定义域名来缓存Blob中的内容。

 

背景介绍:

  在Windows Azure平台上,发送邮件的功能要比你想象的更复杂。

  发送电子邮件对于Windows Azure这样的云平台提出了挑战,因为您没有一个专用的IP地址。那些发送垃圾邮件的人,非常有可能使用Windows Azure来发送垃圾邮件。一旦出现这样的情况,垃圾邮件黑名单会迅速将Windows Azure数据中心的IP地址范围标记为垃圾邮件的来源。这意味着您的合法电子邮件将无法正常发送。  

  对于这些挑战,最佳的解决方案是不从Windows Azure发送电子邮件。而是通过那些有严格的反垃圾邮件规则和专用IP地址的第三方SMTP服务(比如SendGid 或者AuthSMTP)。

  请注意:接收电子邮件是另外一个故事。只要人们愿意发送电子邮件到您的域名,您都可以在Windows Azure接收,只要通过端口号25监听SMTP流量。

 

使用第三方服务发送电子邮件

  我们首先要做的事情是在SendGrid注册一个免费的账户。免费账户允许我们每天发送200封电子邮件,但是他不给我们开放一些高级功能。我们建议您:如果你很关于您的邮件发送过程,请至少升级到银牌(Silver)用户,以保证更好的邮件发送质量。

  一旦我们完成了快速注册,我需要记下所有的细节内容,以便我在配置文件里做添加。

  实际上发送电子是非常容易的,我们可以使用System.Net.Mail这个命名空间。下面的代码是为EmailTheInternet.com发送电子邮件回复

复制代码
var reply = new MailMessage(RoleEnvironment.GetConfigurationSettingValue("EmailAddress"),
    msg.FromAddress)
{
    Subject = msg.Subject.StartsWith("RE:", StringComparison.InvariantCultureIgnoreCase)
                                            ? msg.Subject : string.Format("RE: " + msg.Subject),
    Body = body,
    IsBodyHtml = msg.HasHtmlBody // send HTML if we got HTML
};
if (!reply.IsBodyHtml) reply.BodyEncoding = Encoding.UTF8;
// make it a proper reply
reply.Headers["References"] = msg.MessageID;
reply.Headers["In-Reply-To"] = msg.MessageID;
// use our SMTP server, port, username, and password to send the mail
(new SmtpClient(RoleEnvironment.GetConfigurationSettingValue("SmtpServer"),
    int.Parse(RoleEnvironment.GetConfigurationSettingValue("SmtpPort")))
{
    Credentials = new NetworkCredential(RoleEnvironment.GetConfigurationSettingValue("SmtpUsername"),
        RoleEnvironment.GetConfigurationSettingValue("SmtpPassword"))
}).Send(reply);
复制代码

  请注意:我用的是SendGrid的免费帐号,这意味着我每天只能发有限数量的邮件,我们没有一个固定IP地址和whitelabeling.正因为如此,我的邮件可能无法全部通过垃圾邮件过滤器,一些电子邮件客户端将显示我通过SendGrid发送的邮件为"代表 post@emailtheinternet.com"。这是因为我还没有为这些服务付费(我使用的是免费帐号),不是因为这种方法的缺陷。

 

使用Worker Role接收邮件

  我很惊讶,在C#中找到为接收邮件功能的易用、免费的类库是非常困难的。我参考了Eric Daugherty’s C# Email Server (CSES),然后添加了SharpMimeTools,以处理复杂的、有MIME编码和附件任务。

  您可以阅读代码的细节,但是我基本上做两件事情:

  1. 在OnStart()中执行TcpListener,开始侦听相应的端口。
  2. 在Run()开始循环,处理接收来的每个邮件并保存到Blob中,然后发送回复。

  下面的代码初始化SMTP,然后启动TcpListener(在Onstart()调用)。

listener = new TcpListener(IPAddress.Any,
    RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["SmtpIn"].IPEndpoint.Port);
processor = new SMTPProcessor(RoleEnvironment.GetConfigurationSettingValue("DomainName"),
    new RecipientFilter(), new MessageSpool());
listener.Start();

  请注意:我使用service runtime API来确定正确的端口。

  下面是简单的异步处理传入的TCP连接(在Run()调用)

复制代码
var mutex = new ManualResetEvent(false);
while (true)
{
    mutex.Reset();
    listener.BeginAcceptSocket((ar) =>
        {
            mutex.Set();
            processor.ProcessConnection(listener.EndAcceptSocket(ar));
        }, null);
    mutex.WaitOne();
}
复制代码

最后的代码是处理传入的电子邮件

复制代码
// make a container, with public access to blobs
var id = Guid.NewGuid().ToString().Replace("-", null);
var container = account.CreateCloudBlobClient().GetContainerReference(id);
container.Create();
container.SetPermissions(new BlobContainerPermissions() { PublicAccess=BlobContainerPublicAccessType.Blob });

// parse the message
var msg = new SharpMessage(new MemoryStream(Encoding.ASCII.GetBytes(message.Data)),
    SharpDecodeOptions.AllowAttachments | SharpDecodeOptions.AllowHtml | SharpDecodeOptions.DecodeTnef);

// create a permalink-style name for the blob
var permalink = Regex.Replace(Regex.Replace(msg.Subject.ToLower(), @"[^a-z0-9]", "-"), "--+", "-").Trim('-');
if (string.IsNullOrEmpty(permalink))
{
    // in case there's no subject
    permalink = "message";
}
var bodyBlob = container.GetBlobReference(permalink);
// set the CDN to cache the object for 2 hours
bodyBlob.Properties.CacheControl = "max-age=7200";

// replaces references to attachments with the URL of where we'll put them
msg.SetUrlBase(Utility.GetCdnUrlForUri(bodyBlob.Uri) + "/[Name]");

// save each attachment in a blob, setting the appropriate content type
foreach (SharpAttachment attachment in msg.Attachments)
{
    var blob = container.GetBlobReference(permalink + "/" + attachment.Name);
    blob.Properties.ContentType = attachment.MimeTopLevelMediaType + "/" + attachment.MimeMediaSubType;
    blob.Properties.CacheControl = "max-age=7200";
    attachment.Stream.Position = 0;
    blob.UploadFromStream(attachment.Stream);
}
// add the footer and save the body to the blob
SaveBody(msg, bodyBlob, message, container, permalink);
复制代码

 

 

 

 

 

参考资料 http://blog.smarx.com/posts/emailtheinternet-com-sending-and-receiving-email-in-windows-azure


本文转自Lei Zhang的博客博客园博客,原文链接:http://www.cnblogs.com/threestone/archive/2012/06/26/2563849.html,如需转载请自行联系原作者
目录
相关文章
|
2月前
|
Java Unix 应用服务中间件
使用java service wrapper把windows flume做成服务
使用java service wrapper把windows flume做成服务
|
6月前
|
关系型数据库 MySQL Windows
windows安装mysql报错Remove of the Service Denied!
windows安装mysql报错Remove of the Service Denied!
|
9月前
|
C# Windows
震惊!Windows Service服务和定时任务框架quartz之间原来是这种关系……(上)
震惊!Windows Service服务和定时任务框架quartz之间原来是这种关系……
|
9月前
|
调度 C# Windows
震惊!Windows Service服务和定时任务框架quartz之间原来是这种关系……(下)
震惊!Windows Service服务和定时任务框架quartz之间原来是这种关系……(下)
|
数据采集 安全 Windows
解决关于Windows Defender Antivirus Service自启造成运行python程序时,Windows的cpu和内存占用过高问题
启用“关闭Windwos defender”服务解决阿里云Windows服务器的卡顿问题,并列举了网上一些错误的解决方法。
9928 2
解决关于Windows Defender Antivirus Service自启造成运行python程序时,Windows的cpu和内存占用过高问题
|
6月前
|
Windows
Windows 11 蓝屏 Stop code - SYSTEM SERVICE EXCEPTION What failed - igdkmd64.sys
Windows 11 蓝屏 Stop code - SYSTEM SERVICE EXCEPTION What failed - igdkmd64.sys
106 0
|
人工智能 安全 数据处理
阿里云的WINDOWS service RS 12的使用体验
我,胡颖,来自湖南文理学院国际学院信息管理与信息系统21102班。信息管理与信息系统是一门普通高等学校本科专业,属管理科学与工程类专业。该专业对于学生的要求是接受系统和设计方法以及信息管理方法的基本训练,具备综合运用所学知识分析和解决问题的基本能力。阿里云是全球领先的云计算及人工智能科技平台,致力于以在线公共服务的方式,提供安全、可靠的计算和数据处理能力,让计算和人工智能成为普惠科技。基于培养自己的计算机专业的要求,我决定尝试一下体验阿里云的功能。
|
程序员 C# Windows
Windows Service 小品
Windows Service 小品
114 0
Windows Service 小品
|
SQL 存储 运维
Windows Azure云服务IaaS与PaaS层性能分析
近一直想总结Azure IaaS和PaaS的区别与比较,写个博文详细说明一下。建议读者在阅读之前,先熟悉微软PaaS和IaaS平台的基本概念,再参考本文。
380 0
Windows Azure云服务IaaS与PaaS层性能分析
|
Windows
为加快SAP Commerce Cloud在windows服务器上的启动速度,而禁用的一些服务
为加快SAP Commerce Cloud在windows服务器上的启动速度,而禁用的一些服务
102 0
为加快SAP Commerce Cloud在windows服务器上的启动速度,而禁用的一些服务