無廢話WCF入門教程二[WCF應用的通信過程]

一、概述

  WCF能夠建立一個跨平臺的安全、可信賴、事務性的解決方案,是一個WebService,.Net Remoting,Enterprise Service,WSE,MSMQ的並集,有一副很經典的對比圖如下:

WCF與其他分佈式技術對比表

二、WCF中的 "A","B","C" 介紹

  我們先看個生活中的例子,某一天,公司的領導讓你去送一份合同文件,送文件的過程你可以選擇的交通方式爲“打車”、“公交”、“地鐵”,當然費用是根據發票來報銷的,到了對方公司後你要找到某經理,並且要一份收到合同文件的回執和相關文件。

  要完成這項工作任務我們執行以下幾個主要的步驟:

  (1)我們首先要知道對方公司的地址,引出WCF中的"A"。

  A(Address):英文理解爲"地址",在計算機中是通過一個URI唯一地址標識,通過這個地址我們可以找到我們要調用的WCF服務。

  A解決了:Where to locate the WCF Service?

  (2)我們還要選擇我們的交通方式,每種交通方式達到的結果不一樣。如:打車費用較貴、但是過程舒服些,時間上視道路情況而定。公交最便宜,並且可選擇多條線路。地鐵最方便,但是偶爾會很擠,一般都沒座等等,引出WCF中的"B"。

  B(Binding):英文理解爲"捆綁,綁定", Binding實現在Client和Service通信的所有底層細節。如:我們在客戶端與服務端傳輸的時候採用的是什麼樣的編碼,XML?Text?二進制?...採用哪種傳輸協議進行傳輸,TCP?Http?以及採用什麼樣的機制解決安全問題,SSL?加密?...

  B解決了:How to communicate with service?

  (3)到了對方公司之後我們能做哪些事?I.送合同,II.拿回執。我們不能要求對方公司給我們其他的東西,引出WCF中的"C"。

  C(Contract):英文理解爲"合同",合同是什麼?告訴我們哪些事能做,如些事不能做。 Contract的主要的作用是暴露某個WCF Service所提供的所有有效的方法。Contract實際上是把每個方法的轉化成爲相對應的消息。

  C解決了:What functionalities do the Service provide?

三、Endpoint(終結點)

  WCF實現了網絡系統的各個應用程序的通信。各個應用程序的通信是以“終結點(Endpoint)”的來實現的。我們在上面講的實際例子中的A、B、C即是Endpoint 的組成部分,他是服務器間通信調用的入口。

四、應用程序間通信

  我們在第二和第三項中講了A、B、C與Endpoint,現在正式進入應用程序間的通信。我們還是以剛纔送合同的過程爲例:

  員工A手裏有一張便籤,標記着:地址、綁定、合同.....而合作方手裏也有一張便籤,標記着同樣的內容,並且一直得在等待員工A的出現。只有當便簽上的內容一樣時,合作方A纔會簽署合同回執。

  當我們寄宿WCF服務的時候,我們必須定義一個或是多個終結點,然後Serivce端通過監聽這些終結點來處理Client發來的請求。由於應用程序之間是靠Endpoint來通信,那麼我們在Client端也必須定義終結點,只有當Client與Service的終結點完全匹配的時候才能進行通信。

  如上圖所示:只有EndpointA中的A、B、C與EndPointB中的A、B、C完全匹配時才能通信。EndPointE與EndpointD也是一樣的。

五、實例

  在上一節的教程中我們使用了IIS做爲宿主,客戶端調用WCF服務的是Web應用程序。今天這個小節主要以介紹WCF中傳輸的配置爲主,我們把上一節的內容稍做改動,以體現出"Endpoint"與"A、B、C"。

  由於我在教程一里沒有手寫任何配置的代碼,Client與Service端的Web.config都是自動生成的,當我們添加服務引用時,IDE自動將客戶端的配置文件中Endpoint與引用的服務的Endpoint匹配了。如下代碼所示:

客戶端Web.config:

複製代碼
 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <!--
 4   有關如何配置 ASP.NET 應用程序的詳細消息,請訪問
 5   http://go.microsoft.com/fwlink/?LinkId=169433
 6   -->
 7 
 8 <configuration>
 9     <system.web>
10         <compilation debug="true" targetFramework="4.0" />
11     </system.web>
12 
13     <system.serviceModel>
14         <bindings>
15             <basicHttpBinding>
16                 <binding name="BasicHttpBinding_IUser" closeTimeout="00:01:00"
17                     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
18                     allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
19                     maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
20                     messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
21                     useDefaultWebProxy="true">
22                     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
23                         maxBytesPerRead="4096" maxNameTableCharCount="16384" />
24                     <security mode="None">
25                         <transport clientCredentialType="None" proxyCredentialType="None"
26                             realm="" />
27                         <message clientCredentialType="UserName" algorithmSuite="Default" />
28                     </security>
29                 </binding>
30             </basicHttpBinding>
31         </bindings>
32         <client>
33             <endpoint address="http://localhost/User.svc" binding="basicHttpBinding"
34                 bindingConfiguration="BasicHttpBinding_IUser" contract="WCFService.IUser"
35                 name="BasicHttpBinding_IUser" />
36         </client>
37     </system.serviceModel>
38 </configuration>
複製代碼

 服務端Web.config代碼:

複製代碼
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <configuration>
 3 
 4   <system.web>
 5     <compilation debug="true" targetFramework="4.0" />
 6   </system.web>
 7   <system.serviceModel>
 8     <behaviors>
 9       <serviceBehaviors>
10         <behavior>
11           <!-- 爲避免泄漏元數據信息,請在部署前將以下值設置爲 false 並刪除上面的元數據終結點 -->
12           <serviceMetadata httpGetEnabled="true"/>
13           <!-- 要接收故障異常詳細信息以進行調試,請將以下值設置爲 true。在部署前設置爲 false 以避免泄漏異常信息 -->
14           <serviceDebug includeExceptionDetailInFaults="false"/>
15         </behavior>
16       </serviceBehaviors>
17     </behaviors>
18     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
19   </system.serviceModel>
20  <system.webServer>
21     <modules runAllManagedModulesForAllRequests="true"/>
22   </system.webServer>
23   
24 </configuration>
複製代碼

  由上面的兩個配置文件我們發現,客戶端system.serviceMode節點有我們剛纔講的endpoint,而服務端爲什麼沒有?這不是和我們剛纔講的有違背嗎?好吧,我們承認IDE生成的Web.config中endpoint很隱晦。那麼我們看下面手工修改後[把對看起來很複雜並且對當前的學習無用的配置節刪掉]的配置文件的代碼(我將服務端和客戶端放在一塊了):

複製代碼
 1 <!--Service Web.config-->
 2 <?xml version="1.0" encoding="utf-8"?>
 3 <configuration>
 4   <system.web>
 5     <compilation debug="true" targetFramework="4.0" />
 6   </system.web>
 7   <system.serviceModel>
 8     <services>
 9       <service name="WCFService">
10         <endpoint address="http://localhost/User.svc" binding="basicHttpBinding"
11            contract="WCFService.IUser" />
12       </service>
13     </services>
14   </system.serviceModel>
15 </configuration>
16 
17 <!--Client Web.config-->
18 <?xml version="1.0" encoding="utf-8"?>
19 <configuration>
20   <system.web>
21     <compilation debug="true" targetFramework="4.0" />
22   </system.web>
23   <system.serviceModel>
24     <client>
25       <endpoint address="http://localhost/User.svc" binding="basicHttpBinding"
26          contract="WCFService.IUser" />
27     </client>
28   </system.serviceModel>
29 </configuration>
複製代碼

   修改配置文件後我們執行下,發現WCF服務依然執行成功!!這次的配置文件夠明顯了吧,不論是在服務端還是在客戶端,endpoint中的A、B、C都是完全一樣的。也就是終結點完全匹配!

  那麼第一次的配置文件爲什麼能執行呢?答案是我們把WCF寄宿在IIS上,而IIS默認監聽的就是Http協議[B確定了]並且地址也是相對於IIS上的文件地址[A確定了],合同更不用說了,找到User.svc什麼都有了[C確定了],所以在服務端就沒有必要顯示的寫出system.serviceModel,不信你試試,把服務端的配置文件中system.serviceModel節刪除,程序一樣可以運行!服務器端的endpoint確定了,客戶端的endpoint自然要和服務端去對應,所以IDE在生成客戶端的配置文件裏endpoint寫的很詳細的,而服務端卻沒有endpoint。

六、總結

  這節教程主要描述了應用程序間的通信過程,Endpoint和ABC非常重要,也比較好理解,所以建議儘量的熟練。

七、版權

  轉載請註明出處:http://www.cnblogs.com/iamlilinfeng

活到老,學到老,練到老...
發佈了40 篇原創文章 · 獲贊 10 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章