diff --git a/src/client/Bootstrap.Client/Controllers/Api/InterfaceController.cs b/src/client/Bootstrap.Client/Controllers/Api/InterfaceController.cs
index 9a5f717b..f98a94c5 100644
--- a/src/client/Bootstrap.Client/Controllers/Api/InterfaceController.cs
+++ b/src/client/Bootstrap.Client/Controllers/Api/InterfaceController.cs
@@ -1,4 +1,5 @@
-using Microsoft.AspNetCore.Authorization;
+using Bootstrap.Client.Extensions;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.Net;
@@ -59,17 +60,18 @@ namespace Bootstrap.Client.Controllers.Api
var port = section.GetValue("Port", 25);
var enableSsl = section.GetValue("EnableSsl", false);
- if (!string.IsNullOrEmpty(password))
+ var smtpMessage = new SmtpMessage()
{
- using var mailSender = new SmtpClient(smtpHost)
- {
- Credentials = new NetworkCredential(from, password),
- Port = port,
- EnableSsl = enableSsl
- };
- await mailSender.SendMailAsync(from, to, title, message);
- }
- return true;
+ Host = smtpHost,
+ Password = password,
+ From = from,
+ To = to,
+ Port = port,
+ EnableSsl = enableSsl,
+ Title = title,
+ Message = message
+ };
+ return await smtpMessage.SendAsync();
}
}
}
diff --git a/src/client/Bootstrap.Client/Extensions/SmtpExtensions.cs b/src/client/Bootstrap.Client/Extensions/SmtpExtensions.cs
new file mode 100644
index 00000000..9e6923ae
--- /dev/null
+++ b/src/client/Bootstrap.Client/Extensions/SmtpExtensions.cs
@@ -0,0 +1,148 @@
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Mail;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Bootstrap.Client.Extensions
+{
+ ///
+ /// SmtpExtensions 扩展类
+ ///
+ public static class SmtpExtensions
+ {
+ ///
+ /// 异步发送方法
+ ///
+ public static Task SendAsync(this SmtpMessage message)
+ {
+ message.Push();
+ return Task.FromResult(true);
+ }
+ }
+
+ ///
+ /// SmtpMessage 邮件实体类
+ ///
+ public class SmtpMessage
+ {
+ ///
+ /// 获得/设置 主机地址
+ ///
+ public string Host { get; set; } = "";
+
+ ///
+ /// 获得/设置 邮箱密码
+ ///
+ public string Password { get; set; } = "";
+
+ ///
+ /// 获得/设置 发件人地址
+ ///
+ public string From { get; set; } = "";
+
+ ///
+ /// 获得/设置 收件人地址
+ ///
+ public string To { get; set; } = "";
+
+ ///
+ /// 获得/设置 端口
+ ///
+ public int Port { get; set; }
+
+ ///
+ /// 获得/设置 是否启用 SSL
+ ///
+ public bool EnableSsl { get; set; }
+
+ ///
+ /// 获得/设置 邮件标题
+ ///
+ public string Title { get; set; } = "";
+
+ ///
+ /// 获得/设置 邮件正文
+ ///
+ public string Message { get; set; } = "";
+
+ private static BlockingCollection _messageQueue = new BlockingCollection(new ConcurrentQueue());
+ private static CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
+ private static readonly List _currentBatch = new List();
+ private static Task _logTask = Task.Run(ProcessLogQueue);
+
+ ///
+ /// 将邮件添加到队列中
+ ///
+ public void Push()
+ {
+ if (!_messageQueue.IsAddingCompleted) _messageQueue.Add(this, _cancellationTokenSource.Token);
+ }
+
+ private static async Task ProcessLogQueue()
+ {
+ while (!_cancellationTokenSource.IsCancellationRequested)
+ {
+ var limit = 100;
+ while (limit > 0 && _messageQueue.TryTake(out var message))
+ {
+ _currentBatch.Add(message);
+ limit--;
+ }
+
+ try
+ {
+ if (_currentBatch.Any())
+ {
+ await SendAsync(_currentBatch);
+ _currentBatch.Clear();
+ }
+ await Task.Delay(60000, _cancellationTokenSource.Token);
+ }
+ catch (TaskCanceledException)
+ {
+ break;
+ }
+ }
+ _cancellationTokenSource.Dispose();
+
+ // flush message to file
+ while (_messageQueue.TryTake(out var message)) _currentBatch.Add(message);
+ await SendAsync(_currentBatch);
+ }
+
+ private static async Task SendAsync(IEnumerable messages)
+ {
+ if (messages.Any())
+ {
+ var content = new StringBuilder();
+ SmtpClient? sender = null;
+ string from = "";
+ string to = "";
+ string title = "";
+ foreach (var msg in messages)
+ {
+ if (sender == null)
+ {
+ from = msg.From;
+ to = msg.To;
+ title = msg.Title;
+ sender = new SmtpClient(msg.Host)
+ {
+ Credentials = new NetworkCredential(msg.From, msg.Password),
+ Port = msg.Port,
+ EnableSsl = msg.EnableSsl
+ };
+ }
+
+ // 合并消息
+ content.AppendLine(msg.Message);
+ }
+ if (sender != null) await sender.SendMailAsync(from, to, title, content.ToString());
+ }
+ }
+ }
+}