我們在前面章節中講了寄宿,在前面的實例中也用到了配置文件,這一篇主要講講如何在應用配置文件,提高WCF程式的靈活性。在編寫WCF服務應用程式時,編寫配置項也是其中一項主要工作,在前面的幾個示例中我也使用過配置文件,通過配置文件來簡化代碼。WCF通過公開終結點,向客戶端公開服務,包括服務的地址、服務用... ...
一、概述
我們在前面章節中講了寄宿,在前面的實例中也用到了配置文件,這一篇主要講講如何在應用配置文件,提高WCF程式的靈活性。在編寫WCF服務應用程式時,編寫配置項也是其中一項主要工作,在前面的幾個示例中我也使用過配置文件,通過配置文件來簡化代碼。WCF通過公開終結點,向客戶端公開服務,包括服務的地址、服務用於發送和接收消息的傳輸和消息編碼,以及服務需要的安全類型等。當我們把這些配置項寫入到配置文件後,我們無需編譯即可修改WCF的一些可變信息,提高了程式的靈活性。
註意:
1)在代碼里寫了配置,那麼配置文件中的配置項將不起作用。
2) Web程式在Web.config中配置,應用程式中在App.config中配置。
WCF能夠建立一個跨平臺的安全、可信賴、事務性的解決方案,是一個WebService,.Net Remoting,Enterprise Service,WSE,MSMQ的並集,有一副很經典的對比圖如下:
WCF與其他分散式技術對比表
二、WCF中的 "A","B","C" 介紹
我們先看個生活中的例子,某一天,O2O公司接到一份上門美甲服務訂單,美甲師上門服務的過程可以選擇的交通方式為“電動車”、“公交”、“地鐵”,到了客戶的家裡,你要找到客戶,服務完成之後,需要一份客戶的服務評價和付款確認。
要完成這項工作任務我們執行以下幾個主要的步驟:
(1)我們首先要知道客戶所在的地址,引出WCF中的"A"。
A(Address):英文理解為"地址",在電腦中是通過一個URI唯一地址標識,通過這個地址我們可以找到我們要調用的WCF服務。
(2)美甲師還要選擇相應的交通方式,每種交通方式達到的結果不一樣。如:電動車需要自備車輛,時間上視道路情況而定。公交最便宜,並且可選擇多條線路,時間可控性差。地鐵最方便,但是偶爾會很擠,一般都沒座等等,引出WCF中的"B"。
B(Binding):英文理解為"捆綁,綁定", Binding實現在 客戶端和服務端通信的所有底層細節。比如客戶端與服務端之間傳遞的Message是如何編碼的—— text/XML, binary,MTOM;這種Message的傳遞是採用的哪種Transport——TCP, Http, Named Pipe, MSMQ; 以及採用怎樣的機制解決Secure Messaging的問題——SSL,Message Level Security。
(3)到了客戶家裡之後我們能做哪些事?I.給客戶美甲,II.拿服務評價與付款確認。我們不能要求客戶給其他的東西,引出WCF中的"C"。
C(Contract):英文理解為"合同",合同是什麼?告訴我們哪些事能做,如些事不能做。 Contract的主要的作用是暴露某個WCF Service所提供的所有有效的方法。Contract實際上是把每個方法的轉化成為相對應的消息。從Message Exchange的層面上講,Contract實際上是抱每個操作轉化成為相對應的Message Exchange Pattern——MEP(Request/Response; One-way; Duplex)
4) Behavior: Behavior的主要作用是定製Endpoint在運行時的一些必要的Behavior。比如服務端回調客戶端時超時了;客戶端採用的Credential type;以及是否支持Transaction等。
三、Endpoint(終結點)
WCF實現了網路系統的各個應用程式的通信。各個應用程式的通信是以“終結點(Endpoint)”的來實現的。我們在上面講的實際例子中的A、B、C即是Endpoint 的組成部分,他是伺服器間通信調用的入口。
四、應用程式間通信
我們在第二和第三項中講了A、B、C與Endpoint,現在正式進入應用程式間的通信。我們還是以剛纔上門美甲的過程為例:
美甲師手裡有一張訂單,標記著:地址、綁定、合同.....而客戶手裡也有一張訂單,標記著同樣的內容,並且一直得在等待美甲師的出現。只有當訂單上的內容一樣時,美甲師才會替客戶服務,客戶在服務完成之後會進行服務評價與付款確認。
當我們寄宿WCF服務的時候,我們必須定義一個或是多個終結點,然後 服務端通過監聽這些終結點來處理客戶端發來的請求。由於應用程式之間是靠Endpoint來通信,那麼我們在客戶端也必須定義終 結點,只有當客戶端與服務端的終結點完全匹配的時候才能進行通信。
如上圖所示:只有EndpointA中的A、B、C與EndPointB中的A、B、C完全匹配時才能通信。EndPointE與EndpointD也是一樣的。
五、實例
1)服務配置的主要部分
在.config中配置文件中的configuration節點下麵有:<system.serviceModel></system.serviceModel>節點,在這個節點中主要有三個平級的部分。如下代碼所示:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.serviceModel> <!--配置服務和終結點開始--> <services> <service> <endpoint></endpoint> </service> </services> <!--配置服務和終結點結束--> <!--配置綁定開始--> <bindings> <netTcpBinding> <binding> </binding> </netTcpBinding> </bindings> <!--配置綁定結束--> <!--配置行為開始--> <behaviors> <serviceBehaviors> <behavior> </behavior> </serviceBehaviors> </behaviors> <!--配置行為結束--> </system.serviceModel> </configuration>
Service配置節[必須有]:配置服務、介面和終結點。每個Service都會有以下兩個屬性。name:名稱空間.類名[服務的具體實現類]。behaviorConfiguration:一個在behaviors節點中找到的名稱。
Binding配置節[可有可無]:配置綁定,如http,tcp等。
Behavior配置節[可有可無]:配置行為,如認證等。
2)實例
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true"/> </system.web> <!-- When deploying the service library project, the content of the config file must be added to the host's app.config file. System.Configuration does not support config files for libraries. --> <system.serviceModel> <protocolMapping> <add scheme="http" binding="basicHttpBinding"/> <add scheme="net.tcp" binding="netTcpBinding"/> <add scheme="net.pipe" binding="netNamedPipeBinding"/> <add scheme="net.msmq" binding="netMsmqBinding"/> </protocolMapping> <!--服務--> <services> <!--name:名稱空間.類型名--> <!--behaviorConfiguration:behavior的名稱,請看behavior配置節的名稱--> <service behaviorConfiguration="simpleBehavior" name="WCFService.WCFService" > <!-- 除非完全限定,否則地址將與上面提供的基址相關,每個服務可以有多個Endpoint --> <!-- Address:指定這個Endpoint對外的URI,這個URI可以是個絕對地址,也可以是個相對於baseAddress的 相對地址。如果此屬性為空,則這個Endpoint的地址就是baseAddress--> <!--bindingConfiguration:binding的名稱,請看binding配置節的名稱--> <endpoint name="endpointService" address="http://localhost:8000/WCFService" binding="basicHttpBinding" contract="WCFService.IWCFService"> </endpoint> <!-- 此終結點不使用安全綁定,應在部署前確保其安全或將其刪除--> <!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />--> <host> <!-- 每種傳輸協議的baseAddress,用於跟使用同樣傳輸協議Endpoint定義的相對地址組成完整的地址, 每種傳輸協議只能定義一個baseAddress。HTTP的baseAddress同時是service對外發佈服務說明頁面的URL --> <!-- <baseAddresses> <add baseAddress="http://localhost:8000/"/> </baseAddresses>--> </host> </service> </services> <!--行為--> <behaviors> <serviceBehaviors > <!-- httpGetEnabled - bool類型的值,表示是否允許通過HTTP的get方法獲取sevice的WSDL元數據 --> <behavior name="simpleBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8000/WCFService/metadata" /> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <!--綁定--> <bindings> <basicHttpBinding></basicHttpBinding> <basicHttpContextBinding></basicHttpContextBinding> <netMsmqBinding></netMsmqBinding> <netNamedPipeBinding></netNamedPipeBinding> <webHttpBinding></webHttpBinding> <wsHttpBinding> <binding > <security mode="Transport"> <transport clientCredentialType="None"> </transport> <message clientCredentialType="Certificate"/> </security> </binding> </wsHttpBinding> <wsDualHttpBinding></wsDualHttpBinding> </bindings> </system.serviceModel> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration>
結果如下圖: