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. js模版解析

    function JzRender(tpl, data) { // 模版解析 data是对象则返回字符串,是数组则返回字符串数组 if (data instanceof Array) { var s ...

  2. 在sql server使用链接服务器中访问mysql

    ----创建ODBC链接EXEC sp_addlinkedserver @server = 'MySQL', @srvproduct='MySql' , @provider = 'MSDASQL', ...

  3. 常见寻找OEP脱壳的方法

    方法一: 1.用OD载入,不分析代码! 2.单步向下跟踪F8,是向下跳的让它实现 3.遇到程序往回跳的(包括循环),我们在下一句代码处按F4(或者右健单击代码,选择断点——运行到所选) 4.绿色线条表 ...

  4. jquery文件上传

    http://www.jb51.net/Special/799.htm http://www.oschina.net/project/tag/356/jquery-file-upload

  5. ARCGIS如何进行可视域分析

    可视域分析在不同的领域有着广泛的应用,如火灾监控点的设定,观察哨所的设定等等.军事领域是可视域分析技术应用最广的领域.例如为了设计巡航导弹的航线,就必须对发射点到目标的地形进行分析,包括地形特征优劣分 ...

  6. 基于ADO.NET的SqlHelper类

    1.使用Connection连接数据库的步骤: (1).添加命名空间 System.Data.SqlClient(注意:初学者经常会忘记) (2)定义连接字符串.连接SQL Server 数据库时: ...

  7. excel解析二维数组结构的excel

    public void fileImport(Ufile ufile) throws Exception { String filePath = ufile.getFilePath(); List&l ...

  8. springMVC和mybatis整合,jsp对时间进行格式化

    发现jsp显示的时间,是java Date类型的默认格式,一串鸡肠.... 可在jsp对输出进行格式化: 1.加入taglib <%@ taglib prefix="fmt" ...

  9. JavaScript小知识

    1.<script>标签的出现使整个页面因脚本解析.运行而出现等待: 2.合并脚本,每个 HTTP请求都会产生额外的性能负担,下载一 个 100KB 的文件比下载四个 25KB的文件要快: ...

  10. linux+php+apache web调用python脚本权限问题

    lamp : linux + apache + mysql + php 在近期项目中使用 linux + apache + php调用python脚本是出现以下权限问题: build/bdist.li ...