.NET 工作流: Slickflow开源工作流引擎基础介绍(十) -- 邮件轮询异步发送模块集成
前言:在任务数据生成时,为了让办理任务的用户及时获取到待办任务的主题和内容,需要发送通知类的消息,而电子邮件和手机端的短信通知则是比较普通的消息发送。本文是针对电子邮件异步发送模块的实现来做实例说明。
1. 邮件发送通知的位置
通常任务数据生成时,就需要发送一封邮件通知,邮件内容包括正文和页面地址信息;任务办理人员在接收到邮件后,会及时登录系统进行任务处理,发送邮件通知的好处就在于方便和及时。
但是邮件发送并不是所有的业务客户都需要的一个功能,它不便于紧耦合地在引擎流转环节,即跟任务数据的生成绑定。所以在系统构建时候选择了模块集成方式,跟引擎完全脱离而成为一个独立的模块实现。为了让用户熟悉这一开发方法的好处,特意将复杂系统的模块化构建示意如下:
2. 轮询邮件发送的处理
邮件通知的数据来源就是任务表(WfTasks),通过轮询来处理及时生成的待办任务数据,然后每条待办任务发送相应的邮件通知就可以。这样处理的好处是避免了跟引擎内部功能的紧耦合,让引擎更加专注于流转解析和功能扩展。
/// <summary> /// 待办任务发送邮件通知 /// </summary> public void SendTaskEMail(IList<ProcessEntity> processList, IList<UserEMailEntity> userList) { var wfService = new WorkflowService(); var taskList = wfService.GetTaskListEMailUnSent(); if (taskList != null && taskList.Count() > 0) { foreach (var task in taskList) { Func<TaskViewEntity, IList<ProcessEntity>, IList<UserEMailEntity>, Task> func = SendEMailAsync; BackgroundTaskRunner.FireAndForgetTaskAsync(func, task, processList, userList); } } }
3. 异步邮件发送方法
邮件发送时,需要连接smtp服务器端口,并进行邮件用户的身份验证,所以是一个耗时耗资源的一个任务序列,在具体实现中利用异步方式,可以避免对主过程程序处理的性能影响,异步方法接口如下:
//邮件信息 MailMessage mail = new MailMessage(); mail.Subject = Title; mail.Body = body; mail.From = new MailAddress(SendEMailAccount); //发件人地址 mail.SubjectEncoding = UTF8Encoding.UTF8; mail.BodyEncoding = UTF8Encoding.UTF8; mail.Priority = MailPriority.Normal; mail.IsBodyHtml = true; mail.To.Add(receiveEmail); smtp.SendCompleted += SendCompletedCallback; await smtp.SendMailAsync(mail);//发送邮件
4. HangFire 定时任务
邮件轮询发送时间间隔是每分钟进行,考虑到平台的开放性和兼容性,并没有利用WindowsSerivce来实现,而是采用HangFire自动作业框架来集成,其好处是跨平台的应用直接使用就可以。在.NET CORE的产品中做到代码完全一致。
/// <summary> /// 邮件轮询发送 /// </summary> private void AddJobOfTaskEMailSending() { var wfService = new WorkflowService(); var processList = wfService.GetProcessListSimple(); var msgService = new MessageService(); var userList = msgService.GetUserList(); RecurringJob.AddOrUpdate<MessageService>(s => s.SendTaskEMail(processList, userList), Cron.Minutely); }
5. 总结
邮件发送独立模块的集成是作为企业客户的一个功能需求来实现,从技术框架来看,采用轮询模式独立功能封装,更加适合从外部对引擎组件扩展,其好处是保证了引擎的稳定性,同时也作为一个可选项来让用户自由选择。