码迷,mamicode.com
首页 > Windows程序 > 详细

C# 编写短信发送Window服务

时间:2015-11-04 22:49:44      阅读:381      评论:0      收藏:0      [点我收藏+]

标签:

  我们做项目过程中,一般都会有发送短信的需求。最常见的就是户注册或者登录时发送短信验证码。不同类型的短信发送,我们都可以放到到一张短信表中,然后通过一个定时的作业去执行短信发送。而定时作业的执行,我们就可以通过于Window服务去实现。(本篇只说window服务,具体实现短信发送的可以参考博客:http://www.cnblogs.com/ywl925/archive/2012/11/24/2786105.html

1、首先我们创建一张短信内容表:

 1 CREATE TABLE [dbo].[Message](
 2     [ID] [varchar](36) NOT NULL,                --ID
 3     [MessageContent] [nvarchar](150) NOT NULL,  --短信内容
 4     [Mobile] [varchar](11) NOT NULL,            --手机号
 5     [SendType] [varchar](10) NOT NULL,          --类型
 6     [SendNum] [int] NOT NULL,                   --发送次数
 7     [SendState] [int] NOT NULL,                 --发送状态
 8     [MsgError] [nvarchar](500) NULL,            --错误日志
 9     [Enable] [bit] NOT NULL,                    --数据状态
10     [ModifyDate] [datetime] NOT NULL,           --修改时间
11     [CreateDate] [datetime] NOT NULL,           --创建时间
12  CONSTRAINT [PK_Message] PRIMARY KEY CLUSTERED 
13 (
14     [ID] ASC
15 )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
16 ) ON [PRIMARY]
17 
18 GO

简单记录发送短信需要的一些基本信息。以后有需要发送的短信,直接添加到短信表中。

 

2、创建一个Window服务:

技术分享

 

3、实现一个获取短信并发送的函数:

添加一个短信转换类SmsTran,类中只有一个方法Send。主要实现的功能是:

1)从数据库中获取n条发送状态为未发送并且发送次数小于最大发送次数的短信记录。

2)遍历获取到的集合,调用短信发送接口SendSMS,并更新返回的结果状态(成功、失败或者其他)、发送次数和修改时间。

3)更新本次数据集合到数据库。

 1     public class SmsTran
 2     {
 3         private static int MaxSendNum = 99; //最多发送次数
 4         private static int MaxGetNum = 50; //每次获取的最大条数
 5 
 6         public static void Send()
 7         {
 8             using (var db = new DBContext())
 9             {
10                 var smsServer = new SendSMS();
11                 var messages = db.Set<Message>().Where(s => s.SendState == 0 && s.SendNum <= MaxSendNum).Take(MaxGetNum).ToList();
12                 messages.ForEach(s =>
13                 {
14                     Logger.Debug(null, string.Format("短信发送:{0}, {1}", s.Mobile, s.MessageContent));
15                     var result = smsServer.Send(s.Mobile, s.MessageContent);
16                     if (Convert.ToInt32(result) > 0)
17                     {
18                         s.SendState = 1;
19                         s.SendNum = s.SendNum + 1;
20                         s.ModifyDate = DateTime.Now;
21                     }
22                     else
23                     {
24                         s.SendState = 2;
25                         s.SendNum = s.SendNum + 1;
26                         s.MsgError = result;
27                         s.ModifyDate = DateTime.Now;
28                     }
29                   db.SaveChanges();
31 }); 32 } 33 } 34 }

 这里我采用的微软的EF读写数据。SendSMS类是自己写的一个发送短信帮助类,具体实现的方式可以参考我上面发的博客连接。Logger.Debug是一个简单记录日志的方法,有很多中方式可以实现,例如lognet4。

 

4、添加一个定时器执行短信发送:

在服务中添加命名空间System.Timer。在OnStart中添加一个定时器,定时器的执行事件就是上面我们添加的发送短信的方法。同时简单记录一下日志。

 1     public partial class Service : ServiceBase
 2     {
 3         private Timer timer;
 4 
 5         private object obj = new object();
 6 
 7         public Service()
 8         {
 9             InitializeComponent();
10         }
11 
12         protected override void OnStart(string[] args)
13         {
14             Logger.Debug(null, "短信服务已启动 " + DateTime.Now);
15             timer = new Timer();
16             timer.Interval = 2000;
17             timer.Elapsed += timer_Elapsed;
18             timer.Enabled = true;
19         }
20 
21         void timer_Elapsed(object sender, ElapsedEventArgs e)
22         {
23             lock (obj)
24             {
25                 try
26                 {
27                     SmsTran.Send();
28                 }
29                 catch (Exception ex)
30                 {
31                     Logger.Error(null, "短信服务发送错误!", ex);
32                 }
33             }
34         }
35 
36         protected override void OnStop()
37         {
38             timer.Enabled = false;
39             Logger.Debug(null, "短信服务已停止 " + DateTime.Now);
40         }
41     }

这里有一点需要注意,定时器Timer执行时间到时,如果你上一次的代码没有执行完,它会另起一个线程去执行。所以有可能我们上一次从数据库中取出来的短信还在发送中,没有更新发送状态到数据库,又被重新取出来重复次发送。所以这里我加了一个锁lock,执行完上一次的代码,才允许继续执行。

 

5、添加安装程序

在设计窗口中右键添加安装程序,会生成 serviceInstaller和serviceProcessInstaller两个组件。把serviceProcessInstaller的属性account改写为 LocalSystem。同时可以把serviceInstaller的属性ServiceName改写为你自己的服务程序名。

技术分享

技术分享

 

6、安装和卸载

编译后可以把生成的代码拷贝到你需要的地方,例如我在D盘中添加了一个文件夹SmsService用来放置刚才编译后的服务文件。

然后点击 开始,运行中输入cmd,获取命令提示符。输入:

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe D:\SmsService\SmsService.exe

回车执行便可安装。卸载的华命名如下:

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u D:\SmsService\SmsService.exe

大家可以把上面两个脚本命令保存成两个脚本文件Install.bat和Uninstall.bat添加服务文件夹下,已方便执行。

安装后就可以在window服务中看到刚才我们自己添加的服务了。

技术分享

 

因为我们在代码中添加了日志记录,所以启动服务后,就可以在文件夹下看到日志了。

技术分享

C# 编写短信发送Window服务

标签:

原文地址:http://www.cnblogs.com/wenjunming/p/4936791.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!