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. 安装libudev-dev,解决依赖错误

    http://stackoverflow.com/questions/17181073/ubuntu-12-04-libudev-dev-wont-install-because-of-depende ...

  2. vs2012中添加lib,.h文件方法(原)

    项目.属性.C/C++.附加包含目录:填写附加头文件(*.h)所在目录 分号间隔多项项目.属性.链接器.附加库目录:填写附加依赖库(*.lib)所在目录 分号间隔多项项目.属性.链接器(点前面的+展开 ...

  3. js的事件的绑定

    js的绑定事件 绑定事件有什么用,当你一个按钮点击时需要执行2个函数,就可以用绑定事件,一般只有没绑定事件增加两个onclick函数,第二会覆盖第一个函数的. <!DOCTYPE html> ...

  4. live555+ffmpeg如何提取关键帧(I帧,P帧,B帧)

    live555+ffmpeg如何提取关键帧(I帧,P帧,B帧)开发流媒体播放器的时候,特别是在windows  mobile,symbian(S60)平台开发时,很可能遇到需要自己开发播放器的情况.S ...

  5. 基于 EntityFramework 的数据库主从读写分离

    现在刚开始来研究EntityFramwork,起初是在vs2012中通过工具来创建EF ,但是对我这种不熟悉菜鸟来说 有很多业务用EF做出来还是有点难度的,今天来手动搭建一个EF框架,大神勿喷

  6. td的所有style

    td.style.clear= td.style.posRight=0 td.style.backgroundRepeat= td.style.borderTopStyle= td.style.mar ...

  7. 答:SQLServer DBA 三十问之六:Job信息我们可以通过哪些表获取;系统正在运行的语句可以通过哪些视图获取;如何获取某个T-SQL语句的IO、Time等信息;

    6. Job信息我们可以通过哪些表获取:系统正在运行的语句可以通过哪些视图获取:如何获取某个T-SQL语句的IO.Time等信息: 我的MSDB数据库中有全部的表: sys.all_columns,s ...

  8. css3 text-overflow属性

    页面: <ul> <li>· 测试测试测试测试测试测试</li> <li>· 测试测试测试测试测试测试</li> <li>· 测 ...

  9. Gson运用

    输出对象或者对象的list时,我们一般都是重写toString,和遍历list,但是使用Gson输出对象或者对象的list会非常方便. Gson输出list或者对象.Gson数据没有格式化. impo ...

  10. 第六百一十六天 how can I 坚持

    有时间还是多学点东西吧,webservice.. 晚上看了个电影<我们的十年>,乔任梁死了..买了个大柚子,上火好难受.有些困惑啊. 有没有梦想,只是不想让人来到这这个世界,什么都没留下就 ...