C# 编写短信发送Window服务

  我们做项目过程中,一般都会有发送短信的需求。最常见的就是户注册或者登录时发送短信验证码。不同类型的短信发送,我们都可以放到到一张短信表中,然后通过一个定时的作业去执行短信发送。而定时作业的执行,我们就可以通过于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服务中看到刚才我们自己添加的服务了。

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

时间: 2024-10-13 21:28:37

C# 编写短信发送Window服务的相关文章

c#简单易用的短信发送服务 悠逸企业短信服务

 悠逸企业短信发送服务,是一种比较简单易操作的短信发送服务,使用POST的方式,请求相应地址就可以实现短信发送功能 1 /// <summary> 2 /// 短信发送服务 3 /// </summary> 4 public class ShortMsgHelper 5 { 6 /// <summary> 7 /// 短信服务 账号 8 /// </summary> 9 private static string uid = ConfigurationMan

4、下行短信发送WebService、下行短信发送服务 -功能详细设计 --短信平台

3.  下行短信发送WebService 开发一个WebService,供第三方系统调用,用于发送短信.WebService接收数据后,将信息存储入数据库的短信发送数据表中. WebService参数包括:应用标识.手机号码(字符串数组类型).短信内容.扩展码(3-8位数字).优先级(数字1至5).定时发送时间(可null为即时发送).发送人ID(内部机构人员管理系统的ID).发送人全路径. 同时开发另一个WebService,与原有旧系统接口完全相同,用于调用旧短信平台的第三方系统无缝切换到新

短信发送的流程,硬编码在了服务方法里面,优化方案

短信发送的流程,直接硬编码在服务方法里面,如何优化? 需要建立一个系统的短信发送表,定义短信发送模板: 通过批处理,比如spring batch+quartz,去扫描这个表,来统一进行短信发送处理: 而不是各自service,直接发送短信,这样既造成硬编码,而且又造成入口很多, 导致无法管理,无法追溯短信发送的记录,以及是否发送成功. 版权声明:本文为博主原创文章,未经博主允许不得转载.

短信发送接口被恶意访问的网络攻击事件(二)肉搏战-阻止恶意请求

图形验证码+ip(用户id)+https http://www.cnblogs.com/han-1034683568/p/7040417.html 前言 承接前文<短信发送接口被恶意访问的网络攻击事件(一)紧张的遭遇战险胜>,在解决了短信发送的问题后,长长地舒了口气,也就各忙各的事情去了,本以为应该是个完美的收场,哪知道只是泥泞道路的前一段,收场是收不了了,还是要去应付接下来的烂摊子,因为攻击者并没有停止攻击,虽然恶意请求已经可以被识别并且不会被业务服务器处理,也不会去触发短信发送接口,但是请

destoon 短信发送函数及短信接口修改

// $DT在common.inc.php中定义, $CACHE = cache_read('module.php'); $DT = $CACHE['dt'];  从缓存里读取网站配置信息. //$db 数据库类,$DT 全局配置,$DT['sms'] 开启手机短信,$DT_TIME系统时间,$DT_IP 当前ip地址,$_username当前用户 //DT_CLOUD_UID  DT_CLOUD_KEY 在common.inc.php 中定义 //define('DT_CLOUD_UID',

短信发送接收装置

接到Boss的命令,要求我们做一个在Android手机上运行的小的例子,实现的功能是:通过一个手机向另外一个手机发送数据,另外一个Android手机接收到后通过USB接口输出! 该装置主要由三个步骤组成: 1.发信息 2.接收信息并读取信息内容 3.从 USB 口输出(这里暂时没实现) 就是为了实现一个短信发送,并接收短信内容输出的装置 MainActivity.java 类实现的是发送信息的功能 1 package com.example.android_phone; 2 3 import j

扣丁学堂笔记第11天广播接收器、短信与闹钟服务

1.默认广播 MainActivity package com.example.broadcastreceivertest; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class MainActivity extends Activity { @Override protected void onCre

阿里大鱼短信发送接口开发

一. API接口介绍 alibaba.aliqin.fc.sms.num.send (短信发送) 向指定手机号码发送模板短信,模板内可设置部分变量.使用前需要在阿里大于管理中心添加短信签名与短信模板.测试时请直接使用正式环境HTTP请求地址. [重要]批量发送(一次传递多个号码eg:1381111111,1382222222)会产生相应的延迟,触达时间要求高的建议单条发送 公共参数 请求地址: 环境 HTTP请求地址 HTTPS请求地址 正式环境 http://gw.api.taobao.com

C#如何编写短信接口,以及接口的调用,包括C#.net访问web,并处理返回值的简例。

在系统的开发中我们经常会用到接口,下面给大家介绍一种短信接口的编写与调用. 我们常调用接口来完成一些信息的通知或者发送验证码,那么这些操作是如何完成的呢?来看一下详细的介绍吧! 首先呢,我们需要有一个短信的接口地址这个需要从短信接口提供商哪里购买,附带着接口文档,里面有接口地址与详细的函数,参数等说明. 然后我们就可以编写接口啦! 一.先定义一个静态的方法,返回值为字符串类型,给两个参数(短信内容,发送的手机号). 1.定义一个存放密码的变量"pwd",使用MD5进行加密一下. 2.定