目录

介绍

流程

步骤1:创建以下表

步骤2:创建一个存储过程

步骤3:创建一个作业

步骤4:创建SignalR集线器

步骤5:创建SignalR客户端

步骤6:在启动中注册SignalR

步骤7:创建集线器代理

步骤9:测试应用

结论


介绍

通过我们的应用程序向我们的用户发送通知/提醒是我们的明显要求。这些通知可能是电子邮件、文本/语音消息等。我们有一些选项可用于自动化此过程,例如SQL Server中的数据库邮件(Internet上提供了链接以启用和配置),我们可以创建Windows服务或编写Application_Start方法和计时器可以在每天的某个时间完成这项工作。最近,我被要求每天早上7点自动向应用程序用户发送邮件和文本消息,无论他们是联机还是脱机。

我不想使用以上任何内容,因此决定使用SignalRSqlTableDependencySQL Agent。这个想法是创建一个单独的表来每天记录通知,因为该表是由SQL Agent作业处理的,因此SignalR客户端会初始化SqlTableDependency。它将获取记录并通过我们的ASP.NET应用程序发送邮件/文本消息。

流程

上述解决方案仅在应用程序和服务器启动时才有效。我在这里分享了可用于执行类似任务的工作代码。

步骤1:创建以下表

首先,我们将创建一些表来保存用户、任务等。

CREATE TABLE [dbo].[tblUser]([UserId] [int] NOT NULL,[Name] [nvarchar](255) NOT NULL,[Email] [nvarchar](500) NOT NULL,[Mobile] [nvarchar](15) NOT NULL)
CREATE TABLE [dbo].[tblTask]([TaskId] [int] NOT NULL,[TaskCode] [nvarchar](50) NOT NULL,[TaskDate] [date] NULL,[AssignedTo] [int] NOT NULL,[Status] [nvarchar](50) NOT NULL,[Message] [nvarchar](500) NULL,[ReminderStart] [date] NOT NULL)
CREATE TABLE [dbo].[tblDailyReminder]([ReminderId] [int] IDENTITY(1,1) NOT NULL,[TaskId] [int] NOT NULL,[IsSent] [bit] NOT NULL CONSTRAINT [DF_tblDailyReminder_IsSent]  _DEFAULT ((0))
)

步骤2:创建一个存储过程

这是将由SQL代理每天执行的存储过程。在这里,我们正在获取一些待处理的任务,它们的提醒日期已经开始。

Create PROCEDURE [dbo].[sp_PushReminder]
AS
BEGIN                   Delete From tblDailyReminderInsert into tblDailyReminder(TaskId,IsSent)Select TaskId,0 from tblTask _where Status='Pending'and ReminderStart<=GETDATE()
END
Go

注意:我们必须启用代理服务才能使用SqlTableDependency。

USE master;
GO
ALTER DATABASE <Database_Name> SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE;

步骤3:创建一个作业

右键单击SQL Agent⇒ 作业 ⇒ 新建作业
输入一般信息,例如作业名称。

单击左侧窗格上的步骤。

输入步骤名称,选择数据库,然后在命令框中键入“exec procedure name”。单击确定
在左侧窗格上,单击计划并相应地计划您的工作。

步骤4:创建SignalR集线器

[HubName("ReminderHub")]public class ReminderHub : Hub {private readonly ReminderClient _reminderClient;public ReminderHub() : this(ReminderClient.Instance) {}public ReminderHub(ReminderClient reminderClient) {_reminderClient = reminderClient;}}

步骤5:创建SignalR客户端

public class ReminderClient {private readonly static Lazy<ReminderClient> _instance = new Lazy<ReminderClient>(() => new ReminderClient(GlobalHost.ConnectionManager.GetHubContext<ReminderHub>().Clients));private static SqlTableDependency<tblDailyReminder> _sqltableDependency;public Dictionary<string, string> DictUsers = new Dictionary<string, string>();private ReminderClient(IHubConnectionContext<dynamic> clients) {Clients = clients;var mapper = new ModelToTableMapper<tblDailyReminder>();mapper.AddMapping(s => s.TaskId, "TaskId");mapper.AddMapping(s => s.ReminderId, "ReminderId");_ sqltableDependency = new SqlTableDependency<tblDailyReminder>(ConfigurationManager.ConnectionStrings["LocalConStr"].ConnectionString, "tblDailyReminder", "", mapper);_ sqltableDependency.OnChanged += SqlTableDependency_Changed;_ sqltableDependency.OnError += SqlTableDependency_OnError;_ sqltableDependency.Start();}public static ReminderClient Instance  {get {return _instance.Value;}}private IHubConnectionContext<dynamic> Clients {get;set;}void SqlTableDependency_OnError(object sender, ErrorEventArgs e) {throw e.Error;}void SqlTableDependency_Changed(object sender, RecordChangedEventArgs<tblDailyReminder> e) {if (e.ChangeType == ChangeType.Insert){NotificationDemoEntities notificationDemoEntities = new NotificationDemoEntities();var mailRecepients = notificationDemoEntities.tblDailyReminders.Where(x => x.ReminderId == e.Entity.ReminderId).Include(x => x.tblTask).Include(x => x.tblTask.tblUser).ToList();if (mailRecepients != null && mailRecepients.Count() > 0){SendMailNotification(mailRecepients.FirstOrDefault().tblTask.tblUser.Email, mailRecepients.FirstOrDefault().tblTask.Message);}}}private void SendMailNotification(string Tomail, string message)  {try{MailMessage mailMessage = new MailMessage();SmtpClient smtp = new SmtpClient();mailMessage.From = new MailAddress("FromMailAddress");mailMessage.To.Add(new MailAddress(Tomail));mailMessage.Subject = "Test";mailMessage.IsBodyHtml = true;mailMessage.Body = message;smtp.Port = 587;smtp.Host = "smtp.gmail.com";smtp.EnableSsl = true;smtp.UseDefaultCredentials = false;smtp.Credentials = new NetworkCredential("FromMailAddress", "password");smtp.DeliveryMethod = SmtpDeliveryMethod.Network;smtp.Send(mailMessage);}catch (Exception) {}}#region IDisposable Supportprivate bool disposedValue = false; // To detect redundant callsprotected virtual void Dispose(bool disposing) {if (!disposedValue) {if (disposing){_sqltableDependency.Stop();}disposedValue = true;}}~ReminderClient() {Dispose(false);}// This code added to correctly implement the disposable pattern.public void Dispose() {Dispose(true);GC.SuppressFinalize(this);}#endregion}

步骤6:在启动中注册SignalR

确保将signalR映射到Startup类的Configuration方法中:

public class Startup{public void Configuration(IAppBuilder app)        {app.MapSignalR();}}

步骤7:创建集线器代理

为了每次都能使用它,我们必须创建集线器的代理。我将在Global.asax类的Application_Start()方法中这样做。

protected void Application_Start(){AreaRegistration.RegisterAllAreas();FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);HubConnection hubConnection = new HubConnection("http://localhost:55027/signalr/hubs");hubProxy = hubConnection.CreateHubProxy("ReminderHub");hubConnection.Start();}

步骤9:测试应用

为了进行测试,我们需要手动执行作业。

右键单击该作业,然后开始该作业。工作完成后,我们的代码将被执行,并通过邮件发送通知。

每天或按照您计划的时间执行同一作业。

参考资料

要了解有关SqlTableDependency的更多信息, 请访问  https://www.nuget.org/packages/SqlTableDependency。

结论

我们可以使用上述技术将每日提醒发送给我们的用户。在这里,我们使用了SqlTableDependency对象来捕获数据库更改,并且我们还可以在发送邮件/消息的同时向用户推送应用程序级别的通知。我认为它也可以帮助其他开发人员。欢迎提出建议/查询。

使用SQL Agent和SignalR的每日提醒相关推荐

  1. sq服务启动后又停止_SQL SERVER SQL Agent  服务启动后又停止的解决办法

    查看事件查看器.应用程序日志.报错的显示. 无法加载 DLL xplog70.dll 或它引用的一个 DLL.原因: 126(找不到指定的模块.). 安全起见,我更名了sqlserver bin下的x ...

  2. 让您的数据库服务器与您对话:直接从SQL Agent Jobs发送电子邮件

    Recently, I was asked if I can write and run a specific query and have the results, (if any) emailed ...

  3. SQL Agent服务无法启动如何破

    问题现象 从阿里云上镜像过来的一台的数据库服务器,SQL Agent服务启动不了,提示服务启动后停止.(原数据库服务器是正常的,怀疑跟镜像有关) 如下是系统日志和SQL Agent的日志 SQLSer ...

  4. 提醒事项 android,每日提醒 Pro-提醒事项、时间管理待办清单

    编辑点评 叫人提醒我不如叫APP提醒我 每日提醒 Pro-提醒事项.时间管理&待办清单 介绍 每日提醒 Pro-提醒事项.时间管理&待办清单 [每日提醒]是您贴心的提醒管家! 生活中总 ...

  5. Android 天气APP(三十一)每日提醒弹窗

    上一篇:Android 天气APP(三十)分钟级降水 效果图 每日提醒弹窗 前言 正文 一.弹窗背景 二.每天第一次弹窗 三.弹出每日提示弹窗 四.弹窗的开关 文末 前言   为了增强用户的体验,所以 ...

  6. sqlserver browser无法启动_SQL Server中非sysadmin权限用户在SQL Agent的权限

    https://msdn.microsoft.com/zh-cn/library/ms188283.aspx 1.我们创建非sysadmin用户后,登录ssms时无法查看SQL Server Agen ...

  7. 安卓日历每日提醒_Android实现每天定时提醒功能

    这个是设置定时提醒的功能,即设置几点几分后提醒,用的是给系统设置个时间点,当系统时间到达设置的时间点的时候就会给我们发送一个广播,然后达到时间提醒功能 网上找了很多,遇到了很多坑,经过摸索出来的,比如 ...

  8. 软件内每日提醒功能,可整合到工程中

    一.原理简介 每次向AlarmManager里写入提醒时间,当到达提醒时间激活一个广播接收器,进行相应的提醒窗口弹出或通知,并进行下一次闹钟设置.注意重启的时候需要监听系统的广播,并进行重新设置闹钟, ...

  9. 安卓日历每日提醒_android 设置系统闹钟和系统日历提醒

    现在有一个定时提醒的功能, 用 AlarmManager 自己来做,有多少坑做过的都知道.(应用被kill, 应用保活,息屏,关机重启,多版本兼容问题...).要自己做一个完善的不是 1-2天就能搞定 ...

最新文章

  1. 查找字符串末尾含关键字_Excel教程:用find函数带关键字提取杂乱文本
  2. thirft支持双向通信
  3. 用python画四叶草代码-python turtle工具绘制四叶草的实例分享
  4. WinCE驱动编写小结(转载)
  5. java webstock 在线直播_在线教育直播开发的这些知识你知道吗?
  6. [latex]图片动态缩放的PDF动画示例
  7. 节约内存:Instagram的Redis实践(转)
  8. shell编程题(四)
  9. 一文带你理解如何解决工作中的需求
  10. 【转载】利用压缩网页来提升网站浏览速度
  11. RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用
  12. 浏览器极速模式和兼容模式差异
  13. Windows10重新安装软件商店
  14. 大疆 RoboMaster 3508/2006/GM6020 电机使用教程
  15. 八皇后问题(启发式搜索)
  16. SAP UI5 Simple Form 属性 columnsL,columnsM,columnsXL 的属性深入剖析试读版
  17. 一台计算机上的文件 用户名和密码错误,SMB连接电脑提示用户名密码错误怎么办 看完就明白...
  18. 关于Ajax请求服务器端的处理
  19. 分析Perm()函数功能、代码、时间复杂度
  20. Yolo v3的学习

热门文章

  1. python程序开机自启动_Linux下Python脚本自启动和定时启动的详细步骤
  2. sublime怎么运行go_使用SublimeGDB调试Go程序
  3. java中的等待_Java中更好的等待语法
  4. php重定向mysql_使用.php文件生成MySQL转储
  5. java获取文件中的行号_如何取的Java源代码文件中文件名和行号
  6. 信息科学 计算机 区别,电子信息科学技术和计算机科学技术有什么区别啊
  7. 三八妇女节可以应用的PSD分层模板
  8. 设计灵感|浓浓人文感!中文活动海报设计学习案例
  9. arraylist扩容是创建新数组吗 java_Java 集合,你肯定也会被问到这些
  10. python调用win32_python调用win32接口进行截图