摘要 : 從IIS 7 開始, IIS增長了對非HTTP協議的支持. 所以, 自IIS 7以後, 能夠將NetTcpBinding等非HTTP協議的Bindings直接寄宿在IIS上面. 本文將介紹如何在IIS上配置WCF NetTcpBinding, 而且對其工做的方式進行比較深刻的討論.web
下圖是IIS監聽在HTTP協議上的工做方式. 對HTTP協議的監聽是在內核模式下的HTTP.sys的幫助下完成windows
從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中.瀏覽器
進過拆分以後, 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
一樣, 也須要檢查WCF是否啓用了Non-Http的支持. .Net Framework 3.5和 .Net Framework 4.5分別有各自的支持.
不過上述的Services只會存在一個, 若是服務器上只有.Net Framework 3.5本版的被啓用, 則這些Services則只能使用3.5版本的DLL. 若是.Net Framework 4.5版本一旦被啓用, 不管是否同時啓用了3.5版本, 則會使用4.5版本. 能夠經過服務所使用的SMSvcHost.exe來判斷實際使用了那一個版本.
在IIS中,選中你的網站,而後在右邊的操做菜單欄中單擊綁定,會彈出一個「網站綁定」窗口,點擊添加,類型選擇net.tcp
選擇你的網站,點擊「高級設置」,彈出的的窗體中,在「已啓用的協議」一欄中手動添加:net.tcp. 作完這一步以後, 該網站即增長了對net.tcp協議的支持.
示例是用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.
若是要訪問NetTcpBinding的WCF Service則須要一個一樣採用Net.TCP協議的客戶端. 這裏, 我使用了VS 2012來完成.
下面是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的宿主進程.