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

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. 浅谈 JSON 那些被转义的字符们

    其实,之前我一直以为 JSON 会把 ASCII 可显示字符以外的统统转义为 Unicode,直到有一次我用 JSON.stringify 才发现,其实是 PHP 为我们想的太周到了. 我以前是一位 ...

  2. [python]小技巧集锦

    1.数组过滤,只适用于numpy alpha[alpha>0]:返回alpha中大于0的元素组成的数组 2.在范围内选取不等于某值的数值 j = i while j==i: j = int(ra ...

  3. Linux硬盘的检测(原创)

    http://czmmiao.iteye.com/blog/1058215 概述 随着硬盘容量.速度的快速发展,硬盘的可靠性问题越来越重要,今天的单块硬盘存储容量可轻松达到1TB,硬盘损坏带来的影响非 ...

  4. PHP跨域访问

    1.允许所有域名访问 header('Access-Control-Allow-Origin: *'); 2.允许单个域名访问 header('Access-Control-Allow-Origin: ...

  5. javaweb笔记四

    得到表单数据:1.String str = request.getParameter(String)//根据表单名得到表单值,如果是多个同名的键值,返回第一个值.2.String[] str= req ...

  6. SqlServer行转列(PIVOT),列转行(UNPIVOT)总结

    PIVOT用于将列值旋转为列名(即行转列) 语法: table_source PIVOT( 聚合函数(value_column) FOR pivot_column IN(<column_list ...

  7. django中注册功能signup的测试例

    这个是套路, 有了这些测试用例, 开发就会更有保障, 且每次重写,都好麻烦, 不好cp来得快~~:) from django.test import TestCase from django.urls ...

  8. Java第三阶段学习(十、XML学习)

    一.XML学习 1.模拟Servlet执行 在学习完前端及java与数据库后,将进行WEB编程阶段的学习.在WEB编程中,可以通过浏览器访问WEB服务器上的数据.这时WEB服务器就相当于另一台计算机. ...

  9. 2018年湘潭大学程序设计竞赛 F - maze

    把点抽出来 跑个最短路就好啦. #include<bits/stdc++.h> #define LL long long #define pii pair<int,int> # ...

  10. ubuntu下spark安装配置

    一.安装vmware虚拟机 二.在虚拟机上安装ubuntu12.04操作系统 三.安装jdk1.8.0_25 http://www.oracle.com/technetwork/java/javase ...