WCF : 如何将NetTcpBinding寄宿在IIS7上

摘要 : 从IIS 7 开始, IIS增长了对非HTTP协议的支持. 所以, 自IIS 7以后, 能够将NetTcpBinding等非HTTP协议的Bindings直接寄宿在IIS上面. 本文将介绍如何在IIS上配置WCF NetTcpBinding, 而且对其工做的方式进行比较深刻的讨论.web

 

Windows Process Activation Service

 

下图是IIS监听在HTTP协议上的工做方式. 对HTTP协议的监听是在内核模式下的HTTP.sys的帮助下完成windows

introduction-to-iis-architecture-101-OverviewOfHTTPRequest[1]

 

从IIS7开始,IIS还加入了对非HTTP协议的支持。对于那些采用非HTTP协议,可是又须要部署在IIS里面,从而利用IIS优秀的管理功能的服务来讲,好比WCF服务,可谓一大福音。IIS7能够支持多种非HTTP协议,好比net.tcp,net.msmq, net.pipe等。因为HTTP.sys并不会监听非HTTP协议的端口. 对于非HTTP协议, 则有各自的Windows Serivce来进行监听. 例如Net.Tcp协议, 则是由Net.Tcp Port Sharing Service和Net.Tcp Listener Adapter服务进行监听, 而且寄宿在SMSvcHost.exe中.浏览器

 

Picture1

 

进过拆分以后, WAS不只处理HTTP请求,还能够处理非HTTP协议的请求。HTTP请求是由Http.sys截获的,而且在传递给WAS以前,就已经传递给w3svc中的HTTP管理器,可是,其余请求都是经过WAS侦听器的适配器接口转发给配置管理器和进程管理器的,而没有通过w3svc。服务器

关于 WAS的介绍能够参考这里 :app

http://msdn.microsoft.com/en-us/library/ms734677(v=vs.110).aspxtcp

http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/08/iis-7-support-for-non-http-protocols.aspxide

为了让IIS支持net.tcp,必须先安装WAS(Windows Process Activation Service),即windows进程激活服务。优化

打开控制面板--程序和功能--打开或关闭windows功能,安装WAS,如图:网站

安装完毕后在Services窗口中能够到到以下服务:Windows Process Activation Service;Net.Msmq Listener Adapter;Net.Pipe Listener Adapter;Net.Tcp Listener Adapter;Net.Tcp Port Sharing Service.这几个服务。肯定Net.Tcp Listener Adapter 与Net.Tcp Port Sharing Service是否已经启动。spa

image

一样, 也须要检查WCF是否启用了Non-Http的支持. .Net Framework 3.5和 .Net Framework 4.5分别有各自的支持. 

image

不过上述的Services只会存在一个, 若是服务器上只有.Net Framework 3.5本版的被启用, 则这些Services则只能使用3.5版本的DLL. 若是.Net Framework 4.5版本一旦被启用, 不管是否同时启用了3.5版本, 则会使用4.5版本. 能够经过服务所使用的SMSvcHost.exe来判断实际使用了那一个版本.

image

 

IIS 上的配置

在IIS中,选中你的网站,而后在右边的操做菜单栏中单击绑定,会弹出一个“网站绑定”窗口,点击添加,类型选择net.tcp

image

 

选择你的网站,点击“高级设置”,弹出的的窗体中,在“已启用的协议”一栏中手动添加:net.tcp. 作完这一步以后, 该网站即增长了对net.tcp协议的支持.

image

示例

示例是用VS2012新建的WCF模板. 

 1     public class Service1 : IService1
 2     {
 3         public string GetData(int value)
 4         {
 5             return string.Format("You entered: {0}", value);
 6         }
 7 
 8         public CompositeType GetDataUsingDataContract(CompositeType composite)
 9         {
10             if (composite == null)
11             {
12                 throw new ArgumentNullException("composite");
13             }
14             if (composite.BoolValue)
15             {
16                 composite.StringValue += "Suffix";
17             }
18             return composite;
19         }
20     }


下面是使用了NetTcpBinding的WCF Service的配置.

<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NewBinding1" />
      </netTcpBinding>
    </bindings>
    <services>
      <service name="NetTcpSite.Service1">
        <endpoint binding="netTcpBinding" bindingConfiguration="NewBinding1"
        contract="NetTcpSite.IService1" />
        <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
          contract="IMetadataExchange" />
        
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="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>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

 

因为WCF 4.5对默认配置进行了优化. 因此即便没有关于HTTP协议的任何配置, WCF Service默认状况下也能经过浏览器的方式访问到WSDL.

image

若是要访问NetTcpBinding的WCF Service则须要一个一样采用Net.TCP协议的客户端. 这里, 我使用了VS 2012来完成.

image

下面是WCF客户端的的配置和代码.

    class Program
    {
        static void Main(string[] args)
        {
            using (NetTcpService.Service1Client proxy = new Service1Client())
            {
                Console.WriteLine(proxy.GetData(10));
            }
            Console.ReadLine();
        }
    }

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IService1" />
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://localhost/NetTcpSite/Service1.svc"
                binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IService1"
                contract="NetTcpService.IService1" name="NetTcpBinding_IService1">
                <identity>
                    <servicePrincipalName value="host/LIGHTWEAPON.fareast.corp.microsoft.com" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

  

咱们进一步来观察是哪个进程监听在Net.Tcp占用的808端口上. 从下图上能够验证出, 监听在808端口上的进程是2060. 这个进程ID是SMSvcHost.exe, 也就是上面提到的各类Services的宿主进程.

image

相关文章
相关标签/搜索