美文网首页ABPdotNETAsp.net开发
C# 使用 redis 消息队列功能实现简单的邮件发送系统

C# 使用 redis 消息队列功能实现简单的邮件发送系统

作者: 诸葛_小亮 | 来源:发表于2016-12-03 19:28 被阅读1247次

    背景

    发送在一个系统中现在是不可缺少的一部分了,通常系统内部会建立一套发送邮件机制,类似 abp .net 框架提供的邮件发送功能一样,在需要发送邮件的地方,调用发送邮件的功能,有的系统会将即将发送的邮件先保存到数据库,然后由定时任务不断的从数据库中读取邮件并发送,譬如nop.
    我们知道,邮件发送,属于长时间任务,什么意思呢?也就是说,调用邮件发送功能,这个时候,可能会等待一段时间,ui才会有所响应,在发送邮件的时候,系统处于阻塞状态,abp.net就是这样的,尤其是当发送邮件服务器基本信息有误的时候,导致会等待一段时间,ui才会响应。
    使用定时任务或后台工作任务可以解决上述问题,这里不做描述。
    下面提供另外一种的解决方案,将发送邮件功能脱离系统,使用消息队列方式,也就是说,系统只需向消息队列写消息,而由专门的邮件发送工具或者系统,发送邮件,这样,即使系统所在服务器和邮件发送工具服务器不是同一台电脑,也可以正常使用邮件发送功能。

    背景知识:

    redis 的使用: http://www.jianshu.com/p/0dd7d722c410
    abp.net: http://www.aspnetboilerplate.com/Pages/Documents


    使用 abp 提供的邮件发送功能

    前提:已经运行redis 服务
    使用vs工具新建命令行程序,并引入nuget 包 :abp

    图片.png

    根据abp编写规则,我们需要些一个启动模块,代码如下

    
        public class SendMailModule : AbpModule
        {
            public override void PreInitialize()
            {
                            this.Configuration.Settings.Providers.Add<AppSettingProvider>();
            }
    
            public override void Initialize()
            {
            }
    
            public override void PostInitialize()
            {
            }
        }
    
    

    为了使用 abp 提供的邮件发送内容,我们需要提供一个简单的设置提供者,即 AppSettingProvider ,该提供者提供了基础的发送邮件服务器信息,实现代码如下

    
        public class AppSettingProvider : SettingProvider
        {
            /// <summary>
            /// </summary>
            /// <param name="context"></param>
            /// <returns></returns>
            public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
            {
                return new[]
                           {
                               new SettingDefinition(EmailSettingNames.Smtp.EnableSsl, "true"),
                               new SettingDefinition(EmailSettingNames.Smtp.UseDefaultCredentials, "false"),
                               new SettingDefinition(EmailSettingNames.Smtp.UserName, "自定义账号"),
                               new SettingDefinition(EmailSettingNames.Smtp.Password, "自定义密码"),
                               new SettingDefinition(EmailSettingNames.Smtp.Host, "smtp.qq.com(smtp服务器)"),
                               new SettingDefinition(EmailSettingNames.Smtp.Port, "25(smtp端口)"),
                               new SettingDefinition(EmailSettingNames.DefaultFromAddress, "自定义邮箱,一定要有这个"),
                               new SettingDefinition(EmailSettingNames.DefaultFromDisplayName, "自定义显示名称")
                           };
            }
        }
    
    

    现在我们已经有了基础信息,如果使用邮件发送功能呢?代码如下

    
               /// 启动abp并初始化
                var startup = AbpBootstrapper.Create<SendMailModule>();
                startup.Initialize();
    
    
                // 测试是否可以正常发送
                var emailSender = IocManager.Instance.Resolve<IEmailSender>();
                emailSender.Send("接收地址", "主题", "内容");
    
    

    如果 上述代码正常运行且接收地址收到邮件,则表明我们提供的基础邮件发送服务器信息是正确的。


    使用 redis 提供的队列

    我们在代码中,引入 redis client的nuget包 StackExchange.Redis

    图片.png

    然后通过代码,建立消息队列通道的监听

    
                var sub = redisClient.GetSubscriber();
                sub.Subscribe(
                    "mailtool", 
                    (channel, message) =>
                        {
                            // 假设邮件格式
                            // 收件人地址#主题#内容
                            Console.WriteLine(message);
                            var recMsg = (string)message;
                            var msg = recMsg.Split('#');
    
                            emailSender.Send(msg[0], msg[1], msg[2]);
                        });
    

    并且,随之通过通道发送一条邮件信息

    sub.Publish("mailtool", "目标地址#mailtool测试#我是通过redis 消息队列发出来的");
    

    全部代码如下:

    
        /// <summary>
        /// The program.
        /// </summary>
        internal class Program
        {
            /// <summary>
            /// The redis client.
            /// </summary>
            private static readonly ConnectionMultiplexer redisClient = ConnectionMultiplexer.Connect("localhost");
    
            /// <summary>
            /// The main.
            /// </summary>
            /// <param name="args">
            /// The args.
            /// </param>
            private static void Main(string[] args)
            {
                var startup = AbpBootstrapper.Create<SendMailModule>();
                startup.Initialize();
    
                // 测试是否可以正常发送
                var emailSender = IocManager.Instance.Resolve<IEmailSender>();
                emailSender.Send("目标地址", "主题", "内容");
    
                var sub = redisClient.GetSubscriber();
                sub.Subscribe(
                    "mailtool", 
                    (channel, message) =>
                        {
                            // 假设邮件格式
                            // 收件人地址#主题#内容
                            Console.WriteLine(message);
                            var recMsg = (string)message;
                            var msg = recMsg.Split('#');
    
                            emailSender.Send(msg[0], msg[1], msg[2]);
                        });
                sub.Publish("mailtool", "目标地址#主题#内容");
    
                Console.ReadKey();
            }
        }
    
    
    

    使用 redis 客户端发送邮件

    前提,已经打开 redis 客户端,且运行 邮件发送工具 RedisMailTool
    输入命令: PUBLISH "mailtool" "目标地址#主题#内容"


    图片.png

    邮件会成功发送给目标地址


    总结

    通过上述内容,我们掌握了如何使用redis 提供的消息队列 实现简单的邮件发送工具。
    也掌握了如何使用 abp提供的邮件发送功能发送邮件,同时,该案例,可以作为abp开发非web项目的一个启发。
    同样的,现在越来越多的系统提供发送手机短信功能,我们是不是也可以借助消息队列手段将该功能单独出一个小工具。

    源代码: https://git.oschina.net/zhaord/redismailtool

    我的公众号


    qq:1260825783

    若是需要转载,请备注原地址:http://www.jianshu.com/p/e8f9e46ccc40

    相关文章

      网友评论

        本文标题:C# 使用 redis 消息队列功能实现简单的邮件发送系统

        本文链接:https://www.haomeiwen.com/subject/jepcmttx.html