用asp.net發送Email已經不是一件新鮮的事情了.可以採用很多種方法來發送,比如SmtpMail方法,Socket方法,通過第三方組件Jmail等方式都可以.但是本文討論的不是發送郵件採用的技術,而是通過公司的一個項目(手機主題)實踐說說郵件引擎的架構,有不足和改進之處,歡迎同行批評指正.
我們以前發送郵件的時候採用的方法就是,在頁面裡面觸發進行發送,比如註冊了會員,點了提交按鈕之後,將會員資料插入到資料庫,然後進行發送.這種方法雖然簡單方便,但是有一個弱點,如果郵件發送失敗,就不能重發了.因此,在我們項目中採用的方法是,將需要發送的郵件統一插入到一個郵件隊列,然後由引擎來處理這個隊列.具體的做法是,資料庫設計:
Win_EmailQueue(郵件隊列表)
QueueId int 自動編號,主鍵Id
ToEmail nvarchar(100) 收件者
Title nvarchar(100) 郵件標題
Content ntext 郵件內容
AddDate datetime 添加時間
TryTimes int 錯誤重試次數
LastSendTime datetime 最後一次發送的時間
Status int 狀態:0 未發送 1 已經發送
需要發送郵件的時候,如註冊會員成功後,將郵件的內容插入到表中.
郵件引擎可以用一個系統服務來完成,安裝在Web伺服器同一台伺服器上面,也可以根據負載實際情況安裝在另外一台伺服器上面,減輕Web伺服器負擔.郵件引擎的任務是間隔一個時間(比如5秒),查詢郵件隊列,根據時間順序發送郵件,為了降低引擎的負擔,可以設定每次發送15封,當然這個數字要根據實際情況來配置.
以下是處理隊列和發送郵件的一些代碼.
///
/// 發送Email隊列,來自 手機主題 http://www.shouji138.com
///
public static void SendEmailQueue()
{
//取最新的15條未成功的進行發送。
string sql = "select top 15 * from Win_EmailQueue where Status=0 and ToEmail<>'' order by AddDate desc";
DataTable dt = DbHelperSQL.Query(sql).Tables[0];
for (int i = 0; i < dt.Rows.Count; i++)
{
string title = dt.Rows[i]["Title"].ToString();
string content = dt.Rows[i]["Content"].ToString();
string to = dt.Rows[i]["ToEmail"].ToString();
string CreateTime = dt.Rows[i]["AddDate"].ToString();
string QueueID = dt.Rows[i]["QueueID"].ToString();
bool flag = EmailUtil.Send(title, to, content);
if (flag)
{
//發送成功,將Status設定為1
sql = "update Win_EmailQueue set Status=1 where QueueID=" + QueueID + "";
}
else
{
//發送失敗,將失敗次數增加1
sql = "update Win_EmailQueue set TryTimes=TryTimes+1,LastSendTime='" + DateTime.Now.ToString() + "' where QueueID=" + QueueID + "";
}
DbHelperSQL.ExecuteSql(sql);
}
dt.Dispose();
//超過10次未成功的郵件,將不再發送
sql = "update Win_EmailQueue set Status=1 where TryTimes>10";
DbHelperSQL.ExecuteSql(sql);
}
///
/// 執行發送操作,來自 手機主題 http://www.shouji138.com
///
///
public static bool Send(string title, string to, string content)
{
//來自配置項
string fromemail = System.Configuration.ConfigurationManager.AppSettings["SMTPUserName"];
string smtpserver = System.Configuration.ConfigurationManager.AppSettings["SMTPServer"];
string frompwd = System.Configuration.ConfigurationManager.AppSettings["SMTPPass"];
string fromaddress = System.Configuration.ConfigurationManager.AppSettings["SMTPNickName"];
MailMessage mail = new MailMessage();
mail.From = new MailAddress(fromemail, fromaddress, Encoding.GetEncoding("gb2312"));//寄件者的郵箱
mail.To.Add(new MailAddress(to));//收件者
mail.Subject = title;//主題
mail.Body = content;//內容
mail.IsBodyHtml = true;
mail.SubjectEncoding = Encoding.GetEncoding("gb2312");
mail.BodyEncoding = Encoding.GetEncoding("gb2312");
mail.IsBodyHtml = true;
mail.Priority = MailPriority.Normal;
SmtpClient sc = new SmtpClient(smtpserver);//發郵件的伺服器 手機主題 http://www.shouji138.com
NetworkCredential nc = new NetworkCredential(fromemail, frompwd);//申請的帳戶資訊
sc.Credentials = nc;
bool successflag;
try
{
sc.Send(mail);
successflag = true;
}
catch
{
successflag = false;
}
return successflag;
}
在虛擬機器主機中,也可以採用首頁載入一個script頁面,這個頁面來充當郵件引擎.代碼如下:
ajax/ajaxm.aspx
protected void Page_Load(object sender, EventArgs e)
{
try
{
Email.SendEmailQueue(); //發送郵件
}
catch (Exception ex)
{
Log.SaveException(ex); //儲存錯誤記錄檔
}
Response.Write(" ");
Response.End();
}
然後在首頁或者內頁,插入代碼及可.