1.创建服务

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topshelf; namespace YY.SmsPlatform.MassSendingSms
{
class Program
{
static void Main(string[] args)
{
HostFactory.Run(x => //
{
x.Service<MassSendingSms>(s => //
{
s.ConstructUsing(name => new MassSendingSms()); //
s.WhenStarted(tc => tc.Start()); //
s.WhenStopped(tc => tc.Stop()); //
});
x.RunAsLocalSystem(); // x.SetDescription("大批量短信读取文件信息分包发送"); //
x.SetDisplayName("MassSendingSmsService"); //
x.SetServiceName("MassSendingSmsService"); //
});
}
}
}

2.创建服务控制类型(这个类就是开始、暂停、继续、停止四个方法,本实例就开始与结束,开始代码内是创建了Remoting的远程访问对象)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using YY.SmsPlatform.Common.Host; namespace YY.SmsPlatform.MassSendingSms
{
public class MassSendingSms
{
public void Start()
{
App.InitServiceObject();
//1.
//2.Remoting服务器端激活(SingleCall)
int tcpPort = Convert.ToInt32(ConfigurationManager.AppSettings["TcpPort"]);
TcpChannel channel = new TcpChannel(tcpPort);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MassSendingSmsModule), "MassSendingSmsServer", WellKnownObjectMode.SingleCall);
channel.StartListening(new MassSendingSmsModule());
}
public void Stop()
{
//获得当前已注册的通道;
IChannel[] channels = ChannelServices.RegisteredChannels;
//关闭指定名为MyTcp的通道;
foreach (IChannel eachChannel in channels)
{
if (eachChannel.ChannelName == "MassSendingSmsServer")
{
TcpChannel tcpChannel = (TcpChannel)eachChannel;
//关闭监听;
tcpChannel.StopListening(null);
//注销通道;
ChannelServices.UnregisterChannel(tcpChannel);
}
} }
}
}

3.创建Remoting远程访问类(被访问):

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YY.SmsPlatform.Common;
using YY.SmsPlatform.Common.Data;
using YY.SmsPlatform.Common.Host;
using YY.SmsPlatform.Common.MassSendingSms;
using YY.SmsPlatform.Common.Models;
using YY.SmsPlatform.MassSendingSms.WebService;
using System.Configuration; namespace YY.SmsPlatform.MassSendingSms
{
public class MassSendingSmsModule : MarshalByRefObject ,IMassSendingSmsModule
{
/// <summary>
/// 获取数据源对象
/// </summary>
public static IDataSource DataSource
{
get { return ObjectUtility.DataSource; }
}
//string userName, string password,DateTime? planSendTime,string Ip
public Common.UserInterface.SendResult SendSms(int userId, string password, string mobile, string smsContent, DateTime? planSendTime, string iP)
{
var user = DataSource.GetUserInfo(userId);//获取客户其他信息
string totalId= System.Guid.NewGuid().ToString("N");//创建总ID
DateTime totalTime=DateTime.Now;
//1.验证
//2.短信拆分
var sms = new SmsObject() {
Msisdns="",
SMSContent=smsContent,
PlanSendTime=null,
ExtNumber=null,
};
try
{
using (Stream inStream = new FileStream(mobile, FileMode.Open, FileAccess.Read))
using (StreamReader reader = new StreamReader(inStream, Encoding.Default))
{
//TODO:生成一个总包的ID
string strModile = "";//存储电话号码字符串
string line;//读取到的每一个字符串
int privateIntCountRecord = ;//记录总包条数
//int count = 0;//记录分数量
int i = ;//记录是否满足发送的条数
int partPackageParameter = ;////100位分包大小,TODO:设置为后台参数
string webService = ConfigurationManager.AppSettings["WebServiceUrl"];//获取WebService请求地址
while ((line = reader.ReadLine()) != null)
{
if (!string.IsNullOrWhiteSpace(line))
{
strModile += line + ",";
}
privateIntCountRecord++;
i++;//记录是否满足分包的条数,满足就发送 if (i == partPackageParameter)//达到数量提交
{
//TODO:生成一个分包的id
//count++;//第几个分包
//调用接口发送
WebService.WebService web = new WebService.WebService(); web.Url = webService;//TODO:在配置文件中设置
sms.Msisdns = strModile;
DateTime submitTime = DateTime.Now; SendResult result = web.SendSms(user.UserName, password, sms); var parkPackage = new MASSSENDINGSMS_PARTOFPACKAGE()
{
Description = result.Description,
Error = result.Errors.Join(","),
PartPackageSize = partPackageParameter,
PartSmsid = result.MsgId,
Remark = "",
StatusCode = result.StatusCode.ToString(),
SubmitTime = submitTime,
SuccessCount = result.SuccessCounts,
TotalId = totalId,
UserId = result.CustomId
};
DataSource.InsertIntoMassSendingSmsPartPackage(parkPackage);
//string a =result.StatusCode.ToString();
//将结果及统计数据写入数据库
i = ;
strModile = "";
Trace.TraceInformation("分包提交返回信息:Description(发送描述):" + result.Description + ",Error(错误描述):" + result.Errors.Join(",") + ",ParkPackageSize(分包大小):" + partPackageParameter +
",PartSmsId(分包Id):" + result.MsgId + ",StatusCode(返回状态码):" + result.StatusCode.ToString() + ",TotalId(总包ID):" + totalId + ",客户ID:" + userId + ",成功条数:" + result.SuccessCounts); }
}
if (!string.IsNullOrWhiteSpace(strModile))//最后如果不到分包量时提交一次,while和if中间最好不要插入代码
{
var submitTime = DateTime.Now;
//最后一个包发送
WebService.WebService web = new WebService.WebService();
web.Url = webService;//TODO:在配置文件中设置
sms.Msisdns = strModile;
SendResult result = web.SendSms(user.UserName, password, sms);
//将统计结果写入数据库
var parkPackage = new MASSSENDINGSMS_PARTOFPACKAGE()
{
Description = result.Description,
Error = result.Errors.Join(","),
PartPackageSize = privateIntCountRecord - partPackageParameter,
PartSmsid = result.MsgId,
Remark = "",
StatusCode = result.StatusCode.ToString(),
SubmitTime = submitTime,
SuccessCount = result.SuccessCounts,
TotalId = totalId,
UserId = result.CustomId
};
DataSource.InsertIntoMassSendingSmsPartPackage(parkPackage);
strModile = "";
i = ;
Trace.TraceInformation("分包提交返回信息:Description(发送描述):" + result.Description + ",Error(错误描述):" + result.Errors.Join(",") + ",ParkPackageSize(分包大小):" + partPackageParameter +
",PartSmsId(分包Id):" + result.MsgId + ",StatusCode(返回状态码):" + result.StatusCode.ToString() + ",TotalId(总包ID):" + totalId + ",客户ID:" + userId+",成功条数:"+result.SuccessCounts);
}
var total = new MASSSENDINGSMS_TOTALOFPACKAGE()
{
SmsContent = sms.SMSContent,
TotalId = totalId,
TotalCount = privateIntCountRecord,
TotalSubmitTime = totalTime,
CustomerIp=iP
};
//总包写入数据库
DataSource.InsertMassSendingSmsTotalPackage(total);
Trace.TraceInformation("总包信息:TotalId(总包ID):" + totalId + ",SmsContent(发送内容):" + sms.SMSContent + ",TotalSubmitTime(总包提交时间):" + totalTime +
",客户Ip:" + iP+"总包条数:"+privateIntCountRecord);
return new Common.UserInterface.SendResult() { StatusCode = Common.UserInterface.ResultCode.OK, Description = "具体发送结果请进行查询!" };
} }
catch (Exception ex)
{
Trace.TraceInformation("大批量短信分包发送出现异常:"+ex);
throw new Exception("分包发送发生异常:"+ ex);
} }
}
}

4.Remoting客户端的实现:(此方法中的远程对象没有按照上面实例中写上,我实现的时候是远程对象实现了一个接口客户端创建的是一个远程接口对象)

TcpChannel channel = new TcpChannel();

    ChannelServices.RegisterChannel(channel,false);
    RemotingConfiguration.RegisterWellKnownClientType(typeof(NetRemotingServer.ServerObject),"tcp://localhost:9001/ServerObject");     NetRemotingServer.ServerObject so = (NetRemotingServer.ServerObject)Activator.GetObject(typeof(NetRemotingServer.ServerObject), "tcp://localhost:9001/ServerObject");

5.自己实现的客户端远程对象,有自定义类型,所以也只能是示例不能运行(Remoting客户端通道注册)

#region MassSengdingSms(大批量短信发送远程对象)
public static string WebMassSendingSmsUrl
{
get
{
var v = ConfigurationManager.AppSettings["WebMassSendingSmsUrl"];
if (v == null)
{
v = App.GetSetting("WebMassSendingSmsUrl");
}
return v;
}
}
private static readonly Lazy<IMassSendingSmsModule> massSendingModule= new Lazy<IMassSendingSmsModule>(()=>
{
var webMassSendingSmsUrl = WebObjectUtility.WebMassSendingSmsUrl;
if (webMassSendingSmsUrl == null)
throw new InvalidOperationException("未设置DataSourceUrl");
Trace.TraceInformation("WebMassSendingSmsUrl={0}", webMassSendingSmsUrl);
IMassSendingSmsModule m = (IMassSendingSmsModule)Activator.GetObject(typeof(IMassSendingSmsModule), webMassSendingSmsUrl);
return m;
});
/// <summary>
/// 获取远程大批量短信发送对象
/// </summary>
public static IMassSendingSmsModule MassSendingSmsModule
{
get { return massSendingModule.Value; }
}
#endregion

6.完毕,简单的服务与Remoting远程访问创建

TopShelf框架创建Windows服务作为Remoting的宿主案例:的更多相关文章

  1. Topshelf便捷创建Windows服务

    结合Quartz.net学习,前提已经创建了一个定时任务,可见 <定时调度框架:Quartz.net> (基于配置文件形式) 首先引用Topshelf.dll 自定义服务TestServi ...

  2. 使用Topshelf创建Windows服务

    概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的 ...

  3. [Solution] Microsoft Windows 服务(2) 使用Topshelf创建Windows服务

    除了通过.net提供的windows服务模板外,Topshelf是创建Windows服务的另一种方法. 官网教程:http://docs.topshelf-project.com/en/latest/ ...

  4. Topshelf创建Windows服务

    使用Topshelf创建Windows服务 概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps ...

  5. 【第三方插件】使用Topshelf创建Windows服务

    概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的 ...

  6. 使用Topshelf创建Windows服务[转载]

    概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的 ...

  7. 使用Topshelf组件 一步一步创建 Windows 服务

    我们先来介绍一下使用它的好处,以下论述参考自其他大神. topshelf是创建windows服务的一种方式,相比原生实现ServiceBase.Install.Installer更为简单方便, 我们只 ...

  8. 使用Topshelf 5步创建Windows 服务 z

    使用Topshelf创建Windows 服务简要的介绍了创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with T ...

  9. 使用 Topshelf 结合 Quartz.NET 创建 Windows 服务

    Ø  前言 之前一篇文章已经介绍了,如何使用 Topshelf 创建 Windows 服务.当时提到还缺少一个任务调度框架,就是 Quartz.NET.而本文就展开对 Quartz.NET 的研究,以 ...

随机推荐

  1. IE10中session失效取不到值的问题

    在eworkflow工作流,ebiao报表,eform自定义表单产品升级到IE10的时候,系统登录后,总是会取不到session中的值. for j2ee版本和for dotnet版本都一样取不到值. ...

  2. C++设计模式-TemplateMethod模板方法模式

    Template模板方法模式作用:定义一个操作中的算法的骨架.而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 其关键是将通用算法(逻辑)封装在抽象基 ...

  3. Python-8 元组tuple

    #1 特殊的列表:元组 元组中的元素不可改变 #2 创建.访问 >>> tuple1=(1,2,3) >>> tuple1=1,2,3 >>> t ...

  4. oracle中having的用法

    having的用法,having一般是用在group的后面,用在前面查询结果相同,但是语法上不通顺.答:having是对行组进行过滤.一般是先用where 过滤返回行,用group by 对过滤后的行 ...

  5. GCC的gcc和g++区别

    看的Linux公社的一篇文章,觉得不错,内容复制过来了. 其实在这之前,我一直以为gcc和g++是一个东西,只是有两个不同的名字而已,今天在linux下编译一个c代码时出现了错误才找了一下gcc和g+ ...

  6. javaEE中关于dao层和services层的理解

    javaEE中关于dao层和services层的理解 入职已经一个多月了,作为刚毕业的新人,除了熟悉公司的项目,学习公司的框架,了解项目的一些业务逻辑之外,也就在没学到什么:因为刚入职, 带我的那个师 ...

  7. JavaScript笔记:变量及其作用域

    一.变量的定义及声明 在javascript中变量仅仅是用来保存值的一个占位符而已,定义变量时要使用关键字var后跟一个变量名,如下所示: var message; //定义一个变量message,像 ...

  8. Action向前台输出

    import java.io.IOException;import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse ...

  9. JOST数据 日期转换

    开发中有时候需要从服务器端返回json格式的数据,在后台代码中如果有DateTime类型的数据使用系统自带的工具类序列化后将得到一个很长的数字表示日期数据,如下所示: 复制代码代码如下: //设置服务 ...

  10. Encrypting bootloader (程序BIN文件加密及在线升级)

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 在上一个博客随笔,我介 ...