现在的位置: 首页 > 综合 > 正文

WCF 一步一步发布WCF服务到Windows 服务

2013年09月05日 ⁄ 综合 ⁄ 共 7810字 ⁄ 字号 评论关闭

刚才我们发布了WCF到IIS,下面咱们把WCF,再发布到Windows 服务

WCF是个好东西,对他的赞美之词的确不少,是微软无数开发者的智慧结晶,如果你在学习或者在用WCF,我真的为你感到高兴,在我上学的时候想要去解决兼容性和平衡性能问题,需要那么多专业知识和时间,而现在的WCF,只需要简单的配置就可以实现。

咱们要先用起来是第一步,不落后于时代,不排斥新技术。

如何:在托管 Windows 服务中承载 WCF 服务

本主题概述了创建由 Windows 服务承载的 Windows Communication Foundation (WCF) 服务所需的基本步骤。此方案可通过托管 Windows 服务承载选项启用,此选项是在没有消息激活的安全环境中在 Internet 信息服务 (IIS) 外部承载的、长时间运行的 WCF 服务。服务的生存期改由操作系统控制。此宿主选项在 Windows 的所有版本中都是可用的。

可以使用 Microsoft 管理控制台 (MMC) 中的 Microsoft.ManagementConsole.SnapIn 管理 Windows 服务,并且可以将其配置为在系统启动时自动启动。此承载选项包括注册承载 WCF 服务作为托管 Windows 服务的应用程序域,因此服务的进程生存期由 Windows 服务的服务控制管理器 (SCM) 来控制。

服务代码包括服务协定的服务实现、Windows 服务类和安装程序类。服务实现类 CalculatorService 是 WCF 服务。CalculatorWindowsService 是 Windows 服务。要符合 Windows 服务的要求,该类继承自 ServiceBase 并实现 OnStart 和 OnStop 方法。在 OnStart 中,将为 CalculatorService 类型创建 ServiceHost 并打开它。在 OnStop 中,停止并释放服务。主机还负责提供服务主机基址,该基址已在应用程序设置中进行设置。安装程序类继承自
Installer,允许程序通过 Installutil.exe 工具安装为 Windows 服务。
构造服务并提供宿主代码

使用 Service.cs 文件中的计算器服务接口来定义 ICalculator 服务协定。

通过从 WCF ICalculator 接口继承,在 Service.cs 文件的 CalculatorService 类中实现服务协定作为 WCF 服务。

通过从 ServiceBase 类继承来实现 Windows 服务。重写 OnStart 方法以创建并打开 ServiceHost 的实例。重写 OnStop 方法以关闭 ServiceHost 的实例。创建 CalculatorService 实例的实例并将其命名为“WCFWindowsServiceSample”。提供应用程序的入口点。

创建 ProjectInstaller 类,此类继承自 Installer 并用设置为 true 的 RunInstallerAttribute 来标记,因此,在安装程序集时将调用 Visual Studio 的自定义操作安装程序或 Installutil.exe。

在配置中提供服务的基址。
安装并运行服务

编译服务以生成 Service.exe 可执行文件。

在命令提示符处键入 installutil bin\service.exe 来安装 Windows 服务。(如果尚未设置该工具的路径,则该工具放置在 Microsoft.NET Framework 安装目录中。)在命令提示符处键入 services.msc 以访问服务控制管理器 (SCM)。WINDOWS 服务应作为“WCFWindowsServiceSample”出现在服务中。只有在 Windows 服务正在运行的情况下,WCF 服务才能响应客户端。若要启动服务,请在 SCM 中右击服务并选中“启动”,或在命令提示符处键入
net start WCFWindowsServiceSample。

如果对服务进行更改,则必须首先停止并卸载服务。若要停止服务,请在 SCM 中右击服务并选中“停止”,或在命令提示符处键入 net stop WCFWindowsServiceSample。请注意,如果停止 WINDOWS 服务然后运行客户端,则在客户端尝试访问服务时发生 EndpointNotFoundException 异常。若要卸载 WINDOWS 服务,请在命令提示符处键入 installutil /u bin\service.exe。
示例

下面的代码演示如何将 Service.cs 文件的内容用于协定、协定的实现以及 WINDOWS 服务安装和宿主代码。

与“自承载”选项一样,Windows 服务主机环境要求写入一些宿主代码作为应用程序的一部分。服务作为一个 .exe 程序实现,并包含其自己的宿主代码。在其他宿主环境(如 Internet 信息服务 (IIS) 中的 Windows 进程激活服务 (WAS) 宿主)中,开发人员没有必要编写宿主代码。

 

1:写在前面

我们都知道WCF在运行的时候必须自己提供宿主来承载服务。WCF 本身没有附带宿主,而是提供了一个 ServiceHost 的类,该类允许您在自己的应用程序中host WCF 服务。然后调用 ServiceHost 的 Open 方法即可。我们知道WCF是针对SOA的一套技术.对于SOA而言,我们必须确保服务能够正常运行,平稳的运行,所以此时如何host我们的服务,用什么来Host我们的服务是很重要的,所以我们要为我们的应用程序选择一个合适的Host方式是很有必要的.

2:常见的几种Host

使用Visual Studio.NET可以创建以下几种不同类型的托管应用程序:

WinForms 应用程序

控制台应用程序

Windows 服务

承载于 Internet 信息服务 (IIS) 中的 Web 应用程序

下面我会以一个Demo为例,来介绍这几种常用的host.

3:Hoster特征

在选择应用程序类型时,必须考虑某些特定要求.ServiceHost 必须被实例化才能提供运行服务所需的承载环境。控制台应用程序和 WinForms 应用程序通常运行在用户桌面计算机上。在桌面上是可见的,它们可以承载您的服务,安全性较差.因此并不适用于企业的宿主。因为我们要让我们的企业服务能够支持更大更多的服务,在使用控制台应用程序和 WinForms 应用程序作为host的时候,显然不适合,在这种体系结构中,。这些适用于企业的宿主通常能够满足诸如高可用性的要求。因此,我们不能将控制台或 WinForms 应用程序做为适用于企业的宿主。唯一可行的就是在
IIS 上承载服务或将其Host到Windows 服务。事实上在项目开发过程中我们一般都用windows applicatin或console application做为host.这样有利于调试和测试,而在项目部署的时候,我们一般会选择IIS或windows service作为host. IIS有很多优点,他本身提供了很多功能,

4:Soultion结构图

 

在这个Soultion主要介绍了Console Applicatin,Windows service,IIS三种Host,因为Windows Application和Console Application没有多大区别,暂不作介绍

首先我们介绍在Windows Services中Host WCF service.Windows service 是由操作系统管理的进程,在.net环境中已经提供了这样的模板,以Windows services作为host是一个很不错的选择:

Windows services Host对应用solution中的WCFWindowsServicesHost.

Services Contract和Services

[ServiceContract]
public interface ITest
{
    [OperationContract]
    double add(double x, double y);
}

public class Test:ITest
{     

      public double add(double x, double y)
      {
          return x + y;
      }

}

5:Windows services Host

首先我们建立一个windows service 项目.

 

windows services项目中包含两个文件:service1.cs 文件和 program.cs 文件。其中 service1.cs 文件包含服务实现,而 program.cs 文件则用于实例化并实质上承载 Windows 服务。要在 Windows 服务内部承载 WCF 服务,只需执行 Windows service的 Start() 方法和 Stop() 方法

     ServiceHost host;
      public WindowServiceTest()
      {
          InitializeComponent();
      }

      protected override void OnStart(string[] args)
      {
          host = new ServiceHost(typeof(Test));
          host.Open();          
      }

      protected override void OnStop()
      {
          host.Close();
      }
  配置文件:

<system.serviceModel>
  <behaviors>
    <endpointBehaviors >
      <behavior name="ConsoleApplicationHost">
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <basicHttpBinding>
      <binding name="basicBinding"></binding>
    </basicHttpBinding>
  </bindings> 
  <services>
    <service name="WCFHostServices.Test">
      <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="WCFHostContract.ITest" behaviorConfiguration="ConsoleApplicationHost">
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost/WindowsServiceTest"/>
        </baseAddresses>
      </host>
    </service>
  </services>    
</system.serviceModel>

事实我们可以看到编写host在windows services上的WCF服务很简单,windows services固然有很多好处,比如说随操作系统一起启动,无须人为的开启,而且不限定你的绑定技术,话说windows service 有这么多好处,当然也有不好的地方,比如安装windows service.我们必须通过Installutil.exe 工具或通过安装包中的自定义操作来安装服务。这个工具在安装SDK后会自带的,InstallUtil的使用也很简单,下面我们以自定义安装服务为例

 

在 Windows 服务项目中打开 Service 类的设计器视图。在右击窗口中,单击“添加安装程序”,这样我们就会添加了一个名为ProjectInstaller的组件,在项目中双击这个文件,有一个servicesinstall1的组件,我们右击可以修改他的名字,起动类型等,

 

 

为了创建安装 Windows 服务的安装程序,我们需要向solution中添加安装程序和部署项目(windowsserviceSetup)。以下步骤描述了如何向解决方案添加安装程序和部署项目:

新建一个安装项目:

 

1:右键单击安装项目,指向“添加”,然后选择“项目输出”,选择windows service appliation...选择主输出,

2:右键单击安装项目,指向 view->custome action.

 

3:右击Customer action,将主输出的文件加入custome action中

4:生成项目,并安装,这样我们就可以启动我们的servcies里.我们可以打开windows services管理工具查看我们安装后的servcie

 

 

6:IIS Host

若要在 IIS 中host WCF Services,需要有一个扩展名为 .svc 的文件。事实上在我们项目模板中已经提供了这样的模板.该文件将服务与其实现相关联,并且是 IIS 自动创建 ServiceHost 的手段。IIS 将接管服务与 ServiceHost 之间的交互,不必再由您自己实例化和启动 ServiceHost。.svc 文件的第一行包含一条夹在 ASP.NET <% Page %> 指令内的指令,用于指示文件指向哪个服务。在 IIS 中承载 WCF 服务的默认行为是该 IIS 控制 ServiceHost
的实例化。

我们可以建立一个WCF Services Application,这个文件会自动生Service.svc的文件.

 

我们也可以在其他项目模板中添加svc文件:

 

<%@ ServiceHost Language="C#" Debug="true" Service="WCFIISHost.Test" CodeBehind="Test.svc.cs" %>

在 IIS 中进行host意味着您必须在应用程序的 Web.config 文件中设置 WCF 配置。Web.config 如下

<system.serviceModel>
  <services>
    <service behaviorConfiguration="WCFIISHost.Service1Behavior"
      name="WCFIISHost.Test">
      <endpoint address="" binding="wsHttpBinding" contract="WCFIISHost.ITest">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="WCFIISHost.Service1Behavior">
        <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
        <serviceMetadata httpGetEnabled="true"/>
        <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
        <serviceDebug includeExceptionDetailInFaults="false"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

在 IIS 中host WCF services的默认行为是该 IIS 控制 ServiceHost 的实例化。在Client端我们直接引用地址,默认会在我们的客户端生成代理文件,无须我们使用svcutil工具来生成客户端的代理.

注意:endpoint的address应该为空,以就是说svc 文件将会确定服务的 base 地址

7:Console Application Host

这种方法再简单不过了,因为大多数时候在测试项目的时候,我们都会用这样的host,

Config:

<system.serviceModel>
  <behaviors>
    <endpointBehaviors >
      <behavior name="ConsoleApplicationHost">
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <basicHttpBinding>
      <binding name="basicBinding"></binding>
    </basicHttpBinding>
  </bindings> 
  <services>
    <service name="WCFHostServices.Test">
      <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="WCFHostContract.ITest" behaviorConfiguration="ConsoleApplicationHost">
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost/ConsoleTest"/>
        </baseAddresses>
      </host>
    </service>
  </services>    
</system.serviceModel>

启动Host:

using (ServiceHost host = new ServiceHost(typeof(Test)))
           {
               host.Open();
               Console.WriteLine("Services has begun listenting");
               Console.ReadKey();
           }

Client:

public class CoClient : ClientBase<WCFHostContract.ITest>, ITest
{
    public double add(double x, double y)
    {
        return this.Channel.add(x, y);
    }
}

抱歉!评论已关闭.