建立个windows 服务,添加System.ServiceModel, 添加App.config 配置文件 。
其中, 定义了个变量, runAsService作为,是否用命令行还是使用windows服务来启动项目,这里主要的作用为,在测试时可使用命令行来启动,避免了在修改代码而不断的去更新了已经在系统中注册了的服务。

Program.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace DeliveryService
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
static void Main()
{
// 测试环境用命令行 正式用win服务部署
bool runAsService = Convert.ToBoolean(ConfigurationSettings.AppSettings["RunAsService"] ?? "True");

if (runAsService)
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new DeliveryService() };
ServiceBase.Run(ServicesToRun);
}
else
{
DeliveryService s = new DeliveryService();
s.Test();
}
}
}
}

在配置App.config 文件中添加(其中配置了 刚才提到的 运行方式, 还有win服务的轮询时间, 再后面就是WCF的配置信息了,需要注意的就是ip与端口, 在后面测试要用到。

App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!-- 服务运行方式True以win 服务方式运行,False以控制台方式运行 -->
<add key="RunAsService" value="false"/>
<!-- 轮询时间 -->
<add key="RefTime" value="1"/>
</appSettings>
<connectionStrings>
<!-- DB连接串 -->
<!--<add name="." connectionString="Data Source=.;Initial Catalog=.;User ID=.;Password=.;"/>-->
</connectionStrings>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="65536000" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="myHttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="metadataBehavior" name="DeliveryService.OPService">
<endpoint address="" binding="basicHttpBinding" contract="DeliveryService.IOPService" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:8001/OPService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>

接口,

IOPService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace DeliveryService
{
[ServiceContract]
public interface IOPService
{
[OperationContract]
void TestMethod(int id);
}
}

实现类,

OPService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace DeliveryService
{
public class OPService : IOPService
{
public void TestMethod(int id)
{
Console.WriteLine(id.ToString());
}
}
}

服务代码,主要就是这段了, 没什么难懂的地方.

Service.cs
  1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Diagnostics;
6 using System.Linq;
7 using System.ServiceProcess;
8 using System.Text;
9 using System.Timers;
10 using System.ServiceModel;
11 using System.Threading.Tasks;
12
13 namespace DeliveryService
14 {
15 public partial class DeliveryService : ServiceBase
16 {
17 List<ServiceHost> list = new List<ServiceHost>();
18 Timer _Timer;
19 private static readonly object Locker = new object();
20 public DeliveryService()
21 {
22 InitializeComponent();
23 }
24
25 protected override void OnStart(string[] args)
26 {
27 OpenService();
28 }
29
30 protected override void OnStop()
31 {
32 CloseService();
33 }
34
35 public void Test()
36 {
37 OpenService();
38 Console.ReadLine();
39 CloseService();
40 }
41
42
43 private void InitService()
44 {
45 ServiceHost hostOp = new ServiceHost(typeof(OPService));
46 list.Add(hostOp);
47 }
48
49 private void OpenService()
50 {
51 try
52 {
53 InitService();
54
55 for (int i = 0; i < list.Count; i++)
56 {
57 list[i].Open();
58 }
59
60 InitTimer();
61 }
62 catch (Exception ex)
63 {
64 Console.Write("On_Start 启动服务出错" + ex.ToString());
65 }
66 }
67
68 private void CloseService()
69 {
70 try
71 {
72 for (int i = 0; i < list.Count; i++)
73 {
74 if (list[i].State == CommunicationState.Opened)
75 {
76 list[i].Close();
77 }
78 }
79 CloseTimer();
80 }
81 catch (Exception ex)
82 {
83 Console.Write("On_Stop 结束服务出错" + ex.ToString());
84 }
85 }
86
87 private void InitTimer()
88 {
89 _Timer = new Timer();
90 _Timer.Interval = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["RefTime"]) * (1000 * 60);
91 _Timer.Elapsed += new ElapsedEventHandler(_Timer_Elapsed);
92 _Timer.Enabled = true;
93 _Timer.Start();
94 }
95
96 void _Timer_Elapsed(object sender, ElapsedEventArgs e)
97 {
98 try
99 {
100 lock (Locker)
101 {
102 // to do something
103 }
104 }
105 catch (Exception ex)
106 {
107 Console.Write("_Timer_Elapsed 错误" + ex.ToString());
108 }
109 }
110
111 private void CloseTimer()
112 {
113 if (_Timer != null)
114 {
115 _Timer.Enabled = false;
116 _Timer.Stop();
117 }
118 }
119 }
120 }

至此,发布于windows 服务的WCF 已完成,接下来,再看如何调用此服务提供WebService,

建立个命令行项目吧, 测试简单。添加服务引用,地址就上面app.config配置中的,会自动生成app.config 配置文件,如下:

App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IOPService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://127.0.0.1:8001/OPService" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IOPService" contract="WS_Delivery.IOPService"
name="BasicHttpBinding_IOPService" />
</client>
</system.serviceModel>
</configuration>

再在Program.cs 文件写测试代码,

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestDeliveryService
{
class Program
{
static void Main(string[] args)
{
WS_Delivery.OPServiceClient proxy = new WS_Delivery.OPServiceClient("BasicHttpBinding_IOPService");
Parallel.For(0, 10, new Action<int>((i) =>
{
proxy.TestMethod(i);
}));
}
}
}

启动服务命令行后,运行此项目,测试代码会并行调用wcf 开放出来的webservice 方法。


测试完毕,搞定,收工。。