WCF由 .NET Framework 3.0 (大概在07年前后)開始引入,時隔五年多,才開始學習,再看到一些大牛在幾年前已經 對WCF有比較深入了解,並寫了不少博客,頓感學習之遲鈍、技術之落伍——這其中有些人可能是對新技術的狂熱和興趣,接觸和了解的 比較早,有些人只會等需要用到此新技術時才會去學習,像我。轉入正題,正如這篇博客的標題一樣,我將會以此篇博客為開端,不斷跟大家分享我學習WCF的"所得"——即我眼中的WCF,需要強調的是:我肯定不是權威,我只想把我所知道的用比較通俗的語言寫出來,讓復雜的東西變的簡單易懂點兒,期望每篇博客至少會讓你有一點兒"收獲",這其中難免會有理解錯誤的地方,希望大家能提出來"指正",不拍被拍磚, 但拍磚請友善,因為大家的支持和建議——將是推動我更好更多的寫"WCF學習筆記"此系列的博客的強大動力!
本文目錄:
WCF簡介和由來
WCF(Windows Communication Foundation)是基於Windows平台下開發和部署服務的軟件開發包。它使得開發者能夠建立一個跨平台的安全、可信賴、事務性的解決方案,且能與已有系統兼容協作。WCF是微軟分布式應用程序開發的集大成者,它整合了.Net平台下所有的和分布式系統有關的技術,例如.Net Remoting、ASMX、WSE和MSMQ。以通信(Communiation)范圍而論,它可以跨進程、跨機器、跨子網、企業網乃至於 Internet;以宿主程序而論,可以以ASP.NET,EXE,WPF,Windows Forms,NT Service,COM+作為宿主(Host)。WCF可以支持的協議包括TCP,HTTP,跨進程以及自定義,安全模式則包括SAML, Kerberos,X509,用戶/密碼,自定義等多種標准與模式。也就是說,在WCF框架下,開發基於SOA的分布式系統變得容易,微軟將所有與此相關的技術要素都包含在內,掌握了WCF,就相當於掌握了叩開SOA大門的鑰匙。
隨着SOP和SOA的思想越來越成為潮流,也是現今為了提供分布式部署、高性能和可擴展性的軟件開發的必然趨勢,WCF將會在以后的.net舞台上扮演舉足輕重的角色!
WCF基礎關鍵點(核心)
如圖:
用用例圖來描述WCF的核心——最直接的原因是:我感覺這樣更方便、直觀,以下具體說明:
服務寄宿——首先,‘寄宿’一詞可能就會讓有些人感覺有些模糊難懂,我們可以將其理解為"托管"(在.net中‘托管’一詞想必大家不會陌生),就是說WCF服務不能獨立存在,必須存在(寄宿或托管)於某個進程中。
終結點:描述了一個服務的地址、綁定類型(是http還是tcp等)、服務契約(服務約定接口)。
創建一個WCF服務(HelloWorld WCF)—— IIS寄宿WCF服務
本示例采用的是IIS寄宿,並介紹http(basicHttpBinding)和tcp(netTcpBinding)兩種綁定類型終結點的服務引用!
1.創建WCF服務端,如圖:
2.創建具體的WCF服務,如圖:
添加后會在項目中增加Service1.svc和服務契約IService1.cs接口文件,如圖:
服務契約IService1接口的實現類Service1就是服務類型,代碼如下圖:
3.在IIS中寄宿WCF服務
a.為了便於測試,在本地host中配置:127.0.0.1 www.wcf.dev
b.在IIS中添加服務網站,並指向前面創建好的WCF服務端
c.為了讓此WCF服務支持NetTcpBinding綁定,需如下圖設置:
設置當前WCF服務網站可以被訪問的協議類型為:http,net.tcp
分別設置http和net.tcp協議的網站綁定,需要特別指出的是net.tcp默認端口號是:808
4.創建WCF服務客戶端
服務客戶端基本上不受什么限制,可以靈活的選擇web、WPF/WinForm或控制台項目,本示例選用的web項目作為服務客戶端。服務引用如下圖:
引用服務后,會自動在Web.config中添加如下服務引用配置
<system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1" 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> <netTcpBinding> <binding name="NetTcpBinding_IService1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> <message clientCredentialType="Windows" /> </security> </binding> </netTcpBinding> </bindings> <client> <endpoint address="http://www.wcf.dev/Service1.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="MyService.IService1" name="BasicHttpBinding_IService1" /> <endpoint address="net.tcp://127.0.0.1:808/Service1.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IService1" contract="MyService.IService1" name="NetTcpBinding_IService2"> </endpoint> <endpoint address="net.tcp://127.0.0.1/Service1.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IService1" contract="MyService.IService1" name="NetTcpBinding_IService1"> </endpoint> </client> </system.serviceModel>
到這里,服務已可以在客戶端調用,代碼如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.ServiceModel; 8 9 namespace Web_Client 10 { 11 public partial class _Default : System.Web.UI.Page 12 { 13 protected void Page_Load(object sender, EventArgs e) 14 { 15 #region regName 16 //MyService.Service1Client client = new MyService.Service1Client("NetTcpBinding_IService1"); 17 //Response.Write(client.GetData(123)); 18 //string str = client.GetColorName(MyService.Color.Orange); 19 //Response.Write("<br/>" + str); 20 #endregion 21 Test("BasicHttpBinding_IService1"); 22 Test("NetTcpBinding_IService1"); 23 } 24 25 private void Test(string endpointConfigurationName) 26 { 27 using (ChannelFactory<MyService.IService1> channelFactory = new ChannelFactory<MyService.IService1>(endpointConfigurationName)) 28 { 29 Response.Write("<br/>------------endpointConfigurationName is :" + channelFactory.Endpoint.Name); 30 Response.Write("<br/>------------endpoint Address is :" + channelFactory.Endpoint.Address); 31 MyService.IService1 calculator = channelFactory.CreateChannel(); 32 Response.Write("<br/>" + calculator.GetData(DateTime.Today.Year)); 33 MyService.CompositeType compositeType = calculator.GetDataUsingDataContract(new MyService.CompositeType() { BoolValue = true, StringValue = "This Is Test," + DateTime.Now.ToString() }); 34 Response.Write("<br/>" + compositeType.StringValue); 35 } 36 } 37 } 38 }
測試結果如下圖:
好了,這篇博客就寫到這兒,如果有不清楚的地方,可以給我留言!
文后附上本文的Demo:wcfDemo_Basic.rar