zoukankan      html  css  js  c++  java
  • [转载]WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿

    上面一篇文章中,我们对不同版本的IIS,以及ASP.NET得的实现机制进行了详细而深入的分析。在介绍IIS7.0的时候,我们谈到,HTTP.SYS+W3SVC实现了基于HTTP的请求监听,在此基础上引入了以下三组网络监听器(Listener)和监听适配器(Adapter),实现了基于TCP、Named Pipes和MSMQ的网络监听,图1揭示了IIS7的总体结构。

    • TCPListener|TCP Listener Adapter
    • NamedPipes Listener|Named Pipes Listener Adapter
    • MSMQ Listener|MSMQ Listener Adapter

    image

    图1 IIS 7总体架构

    由于IIS 7提供了基于非HTTP网络协议的监听支持,那么就意味着当我们当我们通过IIS进行WCF服务寄宿(Hosting)的时候,可以采用非HTTP的通信方式。在本篇文章中,我们将通过一个简单实例介绍进行非HTTP的IIS服务寄宿,Source Code下载WasHostingDemo.zip

    由于IIS 7在本质上通过WAS(Windows Process Activation Service)实现了非HTTP的请求监听,我们也可以将这种方式的服务寄宿称为基于WAS的服务寄宿。在本实例中,我们通过IIS 7实现基于TCP的服务寄宿,图2表示实例应用在VS2008种的解决方案结构。其中,Class Library类型的项目Contracts用于定义服务契约;而Services则用于定义具体的服务;Console应用项目Client模拟客户端。此外,Services对应目录被映射为IIS相应站点下的某个Web应用,虚拟目录名称为WasHostingDemo。

    image 

    图2 基于TCP的IIS服务寄宿实例在VS2008中的解决方案结构

    步骤一:定义服务契约和服务

    本实例仍然采用我们熟悉的计算服务的例子,在Contracts项目下,定义了接口ICalculator代表计算服务的服务契约。

    1: using System.ServiceModel;
    2: 
    3: namespace Artech.WasHostingDemo.Contracts
    4: {
    5:     [ServiceContract(Namespace="http://www.artech.com/")]
    6:    public interface ICalculator
    7:     {
    8:         [OperationContract]
    9:        double Add(double x, double y);
    0:     }
    1: }

    在Services项目中,实现了ICalculator接口,提供服务的实现:

    1: using Artech.WasHostingDemo.Contracts;
    2: 
    3: namespace Artech.WasHostingDemo.Services
    4: {
    5:    public class CalculatorService:ICalculator
    6:     {
    7:         #region ICalculator Members
    8: 
    9:         public double Add(double x, double y)
    0:         {
    1:             return x + y;
    2:         }
    3: 
    4:         #endregion
    5:     }
    6: }

    和普通基于HTTP的IIS服务寄宿一样,我们需要为WCF服务创建相应的.SVC文本文件,该文件一般仅仅包含一个<%@ ServiceHost%>指令。简单起见,我仅仅添加了唯一一个必需的Service属性(Attribute)。我把该文件命名为CalculatorService.svc,下面是该.SVC的全部内容:

    <%@ ServiceHost Service="Artech.WasHostingDemo.Services.CalculatorService,Artech.WasHostingDemo.Services"%>

    然后,将Services所在的目录映射为IIS下的虚拟目录。在本例中,在IIS 7的Default Web Site站点下,创建了一个命名为WasHostingDemo的Web应用,并将其物理地址指定为Services项目所在的目录。然后在根目录下创建一个Web.config,配置WCF服务寄宿相关的设置。整个WCF配置如下,Binding类型指定为NetTcpBinding。

    1: <?xml version="1.0" encoding="utf-8" ?>
    2: <configuration>
    3:     <system.serviceModel>
    4:         <services>
    5:             <service name="Artech.WasHostingDemo.Services.CalculatorService">
    6:                 <endpoint address="" binding="netTcpBinding" bindingConfiguration=""
    7:                     contract="Artech.WasHostingDemo.Contracts.ICalculator" />
    8:             </service>
    9:         </services>
    0:     </system.serviceModel>
    1: </configuration>

    注:由于ASP.NET应用在运行的时候默认从根目录下的Bin子目录加载Assembly,而Services项目默认编译的目标目录为Bin\Debug|Release,所以我们需要通过修改项目属性将编译的目标目录设为Bin。

    步骤二:为站点设置TCP绑定,为Web应用添加支持协议

    进行非HTTP的服务寄宿是WAS为WCF提供的最显著的特性。由于在默认的情况下,IIS仅仅支持对于HTTP请求的处理,我们需要相应的方式对IIS相关配置进行相关的修改,从而改变IIS默认的请求处理行为。在上面我们说过,IIS 7.0广泛采用了基于XML文件的配置方式,所以最终极的方式就是直接修改相应的配置文件。但是,直接修改配置文件的方式,出错的频率很高,对于很多的配置,我们都可以直接通过IIS管理器进行相应的修改。此外,我们可以选择通过命令行的方式修改相应的配置,IIS为我们提供了一系列的命令。

    WAS的配置保存在配置文件applicationHost.config中,该文件保存在%windir%\system32\inetsrv\config目录中。为了实现基于非HTTP的服务寄宿,首先需要做的是为WCF Service的寄宿应用所在的Web Site添加非相应非HTTP协议的站点绑定(site binding),该操作可以通过执行Appcmd.exe命名实现,该命名存放在%windir%\system32\inetsrv\目录中。

    为了使寄宿WCF服务的Web站点具有基于TCP的监听能力,我们可以通过下面的命名行为该站点(Default Web Site)添加基于TCP的绑定,指定监听端口为808(默认端口)。

    appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']

    站点绑定添加于修改也可以直接通过IIS管理器进行:选择相应站点=〉在右边的部分“Bindings”=〉在弹出的Site Bindings对话框中可以添加新的站点绑定和编辑现有的站点绑定,如图3所示。

    image

    3 通过IIS管理器设置站点绑定

    在站点级别非HTTP绑定存在的情况下,你还可在应用级别控制对非HTTP协议的支持。在默认的情况下,Web应用并不提供对非HTTP协议的支持,你需要通过AppCmd.exe为应用添加对于某个非HTTP协议支持的能力。通过下面的配置对默认站点下的WasHostingDemo应用添加了对net.tcp支持的能力。

    appcmd.exe set app "Default Web Site/WasHostingDemo" /enabledProtocols:net.tcp

    步骤三:创建客户端程序进行服务调用

    对于调用非HTTP协议的IIS寄宿服务的客户端来说,和普通的WCF服务调用完全一样,下面是服务调用代码和相关的配置。由于,客户端程序通过访问WCF服务的.SVC文件的方式进行服务的调用,所以在相应终结点中的地址为.SVC所在的地址。

    1: using System;
    2: using System.ServiceModel;
    3: using Artech.WasHostingDemo.Contracts;
    4: 
    5: namespace Artech.WasHostingDemo.Client
    6: {
    7:     class Program
    8:     {
    9:         static void Main(string[] args)
    0:         {
    1:             using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorservice"))
    2:             {
    3:                 ICalculator calculator = channelFactory.CreateChannel();
    4:                 using (calculator as IDisposable)
    5:                 {
    6:                     try
    7:                     {
    8:                         Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, calculator.Add(1, 2));
    9:                     }
    0:                     catch (CommunicationException)
    1:                     {
    2:                         (calculator as ICommunicationObject).Abort();
    3:                         throw;
    4:                     }
    5:                     catch (TimeoutException)
    6:                     {
    7:                         (calculator as ICommunicationObject).Abort();
    8:                         throw;
    9:                     }
    0:                 }
    1:             }
    2:         }
    3:     }
    4: } 
       1: <?xml version="1.0" encoding="utf-8" ?>
       2: <configuration>
       3:   <system.serviceModel>
       4:     <client>
       5:       <endpoint address="net.tcp://127.0.0.1/WasHostingDemo/CalculatorService.svc"
       6:       binding="netTcpBinding" bindingConfiguration="" contract="Artech.WasHostingDemo.Contracts.ICalculator"
       7:       name="calculatorservice" />
       8:     </client>
       9:   </system.serviceModel>
      10: </configuration>

    通过运行客户端程序,你将得到如下的输出:

       1: x + y = 3 when x = 1 and y = 2
  • 相关阅读:
    (转载)SAPI 包含sphelper.h编译错误解决方案
    C++11标准的智能指针、野指针、内存泄露的理解(日后还会补充,先浅谈自己的理解)
    504. Base 7(LeetCode)
    242. Valid Anagram(LeetCode)
    169. Majority Element(LeetCode)
    100. Same Tree(LeetCode)
    171. Excel Sheet Column Number(LeetCode)
    168. Excel Sheet Column Title(LeetCode)
    122.Best Time to Buy and Sell Stock II(LeetCode)
    404. Sum of Left Leaves(LeetCode)
  • 原文地址:https://www.cnblogs.com/fx2008/p/2288107.html
Copyright © 2011-2022 走看看