前言:在任务数据生成时,为了让办理任务的用户及时获取到待办任务的主题和内容,需要发送通知类的消息,而电子邮件和手机端的短信通知则是比较普通的消息发送。本文是针对电子邮件异步发送模块的实现来做实例说明。

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. 总结

邮件发送独立模块的集成是作为企业客户的一个功能需求来实现,从技术框架来看,采用轮询模式独立功能封装,更加适合从外部对引擎组件扩展,其好处是保证了引擎的稳定性,同时也作为一个可选项来让用户自由选择。

Slickflow.NET 开源工作流引擎基础介绍(十) -- 邮件轮询异步发送模块集成的更多相关文章

  1. Slickflow.NET 开源工作流引擎基础介绍(二) -- 引擎组件和业务模块的交互

    集成流程引擎的必要性 业务过程的变化是在BPM系统中常见的现象,企业管理层需要不断优化组织架构,改造业务流程,不可避免地带来了业务流程的变化,企业信息系统就会随之面临重构的可能性.一种直接的方式是改造 ...

  2. Slickflow.NET 开源工作流引擎基础介绍(二) -- 引擎组件和业务系统的集成

    集成流程引擎的必要性 业务过程的变化是在BPM系统中常见的现象,企业管理层需要不断优化组织架构,改造业务流程,不可避免地带来了业务流程的变化,企业信息系统就会随之面临重构的可能性.一种直接的方式是改造 ...

  3. Slickflow.NET 开源工作流引擎基础介绍(七) -- 并行分支多实例模式实现

    前言:并行审批是比较常见的流程模式,在工作流模式介绍中,通常是多个分支通过网关(Gateway)来控制实现.默认的分支类型是静态定义好的.本文扩展了并行网关的控制方式,实现了动态多实例的并行分支网关, ...

  4. Slickflow.NET 开源工作流引擎基础介绍(六)--模块化架构设计和实践

    前言:在集成Slickflow.NET 引擎组件过程中,引擎组件需要将用户,角色等资源数据读取进来,供引擎内部调用:而企业客户都是有自己的组织架构模型,在引入模块化架构设计后,引擎组件的集成性更加友好 ...

  5. Slickflow.NET 开源工作流引擎基础介绍(一) -- 引擎基本服务接口API介绍

    1. 工作流术语图示                                              图1 流程图形的BPMN图形元素表示 1) 流程模型定义说明流程(Process):是企 ...

  6. Slickflow.NET 开源工作流引擎基础介绍(九) -- .NET Core2.0 版本实现介绍

    前言:.NET Core 是.NET Framework的新一代版本,是微软开发的第一个跨平台 (Windows.Mac OSX.Linux) 的应用程序开发框架(Application Framew ...

  7. Slickflow.NET 开源工作流引擎基础介绍(八) -- 自动化任务调度实现介绍

    前言:审批流程中常见的都是人工类型任务,但是也会有一些自动化的任务需要定时触发.因此,引擎框架中需要解决掉两个问题:选择合适的任务调度框架,集成新的任务调度模块. 1. 任务调度框架选择 Hangfi ...

  8. Slickflow.NET 开源工作流引擎基础介绍-.NET Core2.0 版本实现介绍 (转)

    前言:.NET Core 是.NET Framework的新一代版本,是微软开发的第一个跨平台 (Windows.Mac OSX.Linux) 的应用程序开发框架(Application Framew ...

  9. Slickflow.NET 开源工作流引擎基础介绍(四) -- 多数据库支持实现

    前言:引擎作为中间件集成到用户的项目里面去,针对用户的数据库类型,需要作出SQL部分的分别实现.引擎默认数据库为MS SQLSERVER,同时也支持ORACLE, MYSQL, KINGBASE等不同 ...

随机推荐

  1. WebViewJavascriptBridge测试示例

    android或ios:app与html5通信解决方案 下面只是前端示例代码,后端代码请参考: git https://github.com/marcuswestin/WebViewJavascrip ...

  2. ecshop 2.7.x 批量测试

    下面为测试是否存在漏洞的脚本: sub MAIN($url) { use HTTP::UserAgent; my $r = HTTP::Request.new(); $r.uri: $url~'/us ...

  3. 【ARTS】01_01_左耳听风-20181112~1116

    每周至少做一个 leetcode 的算法题.阅读并点评至少一篇英文技术文章.学习至少一个技术技巧.分享一篇有观点和思考的技术文章.(也就是 Algorithm.Review.Tip.Share 简称A ...

  4. Spring面试问答25题

    1.什么是Spring框架?Spring框架有哪些主要模块? Spring框架是一个为Java应用程序的开发提供了综合.广泛的基础性支持的Java平台.Spring帮助开发者解决了开发中基础性的问题, ...

  5. shell expect的简单用法【转】

    用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写却不知其然.本文用一个最短的例子说明脚本的原理. 脚本代码如下:  ######## ...

  6. Android Studio引用第三方jar包(例如:使用LitePal)

    如何使用LitePal的教程网上很多,不过对于新手,这些教程中遗漏了将第三方jar包拷贝到app->libs路径下后,还需要add as library. 下载LitePal 这时操作步骤如下: ...

  7. thymeleaf : EL1050E The arguments (...) for the constructor call are missing

    <a href="list.html" th:href="${#strings.replace(new.href,'{page}',1)}" >MO ...

  8. Python外部脚本调用Django项目Model表

    在实际生产中有时候会出现这种情况,原本运行了一个Django项目,后面又需要一些外部脚本进行辅助,而这些脚本又不希望集成到项目当中,但是又需要用到Django项目的Model,这时候是无法像在项目当中 ...

  9. Ruby语言学习笔记

    在codecademy上开始玩ruby了 1.数据类型:boolean,string,number 变量直接用即可,不用声明(“拿来主义”) 运算符:+ - * / ** % == != && ...

  10. 【转】Git命令大全(非常齐全)

    $ git init  // 初始化一个Git仓库$ git status   // 查看仓库的状态$ git add .   // 将所有修改添加到暂存区$ git add *  // Ant风格添 ...