WCF技術的不一樣應用場景及其實現分析

歷史背景:

WCF,全稱是Windows Communication Founcation,它做爲微軟新一代的通信技術,首先正式出如今.NET Framework 3.0中,伴隨着Windows Vista的發佈而名聞遐邇。在此以前,曾經做爲Winfx的一部分爲人所知,其代號爲indigo。外語屋javascript

做爲Foundation(基礎模塊),WCF是定位在微軟.NET平臺上實現統一的消息服務通信機制。它很好地吸取了以前的多種分佈式開發技術的優勢,而且提供了統一的編程和訪問的模型,逐漸成爲SOA解決方案中的主流技術,受到了普遍的關注和使用。php

image

核心要素:

從技術層面理解WCF,能夠分爲三個要素(俗稱WCF的ABC)html

1.Address(where):地址,是指訪問服務的URI(能夠是一個http地址,也能夠是tcp的地址)java

2.Binding(how):綁定,是指通信所使用的協議,例如http,net.tcp,msmq等等jquery

3.Contract(what):合約,是指通信的規範,例如服務的合約,數據的合約等等。android

 

從系統層面理解WCF,能夠分爲四個要素web

1.Contract:合約,定義一套合約,一般是WCF開發的起點。這也是惟一須要在宿主和客戶端之間共享的信息,一般是一些接口(interface)定義。編程

2.Service:服務,基於合約實現的一個具體服務。一般是一些類型(class)定義,實現了業務邏輯。json

3.Host:宿主,既然服務是一個class,它自身是沒法對客戶端請求進行響應的。因此須要有一個宿主程序來提供持續的監聽。WCF的宿主能夠是任意的應用程序,很是靈活。瀏覽器

4.Client:客戶端,任何客戶端(例如Windows Forms,WPF, Silverlight,Console Application,甚至Javascript,或者java,php等等)均可以經過本身的方式來訪問WCF.

 

應用場景:

WCF 從發佈到如今的將近5年左右的時間,通過了屢次加強和改進,從最開始單純的SOAP Service的方式,發展出來其餘多種應用場景,分別是

1. SOAP Services

2. WebHttp Services

3. Data Services

4. Workflow Services

5. RIA Services

 

下面我將針對這些應用場景一一進行講解

【注意】我常用WCF技術以及一些講座中,都會感慨WCF配置的強大。宿主和客戶端均可以經過配置文件的方式定義、更改WCF服務的行爲。能夠這麼說,在WCF中,幾乎什麼均可以配置。這確實很酷。因此下面的講解,不少都是用配置文件的方式來講明問題。android中記錄讀取配置信息

 

1. SOAP Services

這種場景是WCF一開始就支持的,也是最完整的一個。

爲何稱爲SOAP Services呢?這是由於WCF服務是基於消息的通信機制,而它的消息是被封裝爲一個SOAP Envelope(SOAP 信封的)

【備註】SOAP的全稱是Simple Object Access Protocol,咱們通常翻譯爲簡單對象訪問協議。

一個典型的SOAP Request(表明了客戶端發到服務器的請求)

image

一個典型的SOAP Response

image

這 種服務是以操做(Operation)爲中心的,也就是說,咱們能夠徹底控制服務的全部細節,包括定義合約,實現服務,實現宿主等等。這裏面有兩層意思, 咱們將有足夠的靈活性,由於全部一切都是能夠控制的;同時,咱們也須要具有足夠的專業知識,由於全部一切都須要你本身控制。

咱們來看一個典型的WCF SOAP Service的配置文件

<system.serviceModel>     <services>       <service name="WcfService2.Service1" behaviorConfiguration="WcfService2.Service1Behavior">         <!-- Service Endpoints -->         <endpoint address="" binding="wsHttpBinding" contract="WcfService2.IService1">           <!--   Upon deployment, the following identity element should be removed or replaced to reflect the   identity under which the deployed service runs. If removed, WCF will infer an appropriate identity   automatically.  -->           <identity>             <dns value="localhost"/>           </identity>         </endpoint>         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>       </service>     </services>     <behaviors>       <serviceBehaviors>         <behavior name="WcfService2.Service1Behavior">           <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->           <serviceMetadata httpGetEnabled="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>   </system.serviceModel>

 

SOAP Services是從.NET Framework 3.0一開始就提供的,在後續版本中,也有不少改進,包括對WS-*標準更好的支持,以及提供了不少默認的配置選項,簡化了配置的工做。

【備註】值得一提的是,微軟研發集團上海辦公室這邊有一個團隊,直接參與了WCF的新版本的不少功能和工具的設計和開發,包括對於配置的簡化設計。感謝他們的工做。

 

咱們來看一個.NET Framework 4.0下面的WCF服務默認的配置文件

<system.serviceModel>     <behaviors>       <serviceBehaviors>         <behavior>           <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->           <serviceMetadata httpGetEnabled="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>     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />   </system.serviceModel>

經過簡單地比較就能夠知道,在.NET Framework 4.0中,咱們並無看到端點(EndPoint)的定義,這是怎麼回事呢?難道如今不須要定義端點了嗎?固然不是,區別在於,.NET Framework4的ServiceHost將自動地註冊幾個默認的EndPoint。

【備註】若是不是爲了在開發階段調試須要而開啓元數據和調試支持,上面的配置文件,甚至能夠是空的,什麼都不須要定義。

 

關於ServiceHost以及默認的端點的信息,有興趣能夠參考

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicehost.aspx

 

總結:採用這種方式進行開發的WCF,能夠根據咱們的需求,使用任意的Binding,以支持不一樣的客戶端,而且提供在不一樣的場合下最好的速度,還能夠實現諸如緩存,隊列,事務協調等高級功能。

 

2. WebHttp Services

這種服務的出現,是基於一個比較熱的概念:RESTFul。能夠這麼說,這是WCF Restful的一個具體實現。從.NET Framework 3.5開始提供。

所謂RESTFul的概念,有興趣能夠參考 http://zh.wikipedia.org/wiki/REST 以及我以前寫過的一些博客文章:http://zzk.cnblogs.com/s?w=blog%3Achenxizhang%20rest

 

大體的意思是:

表象化狀態轉變(英文:Representational State Transfer,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟件架構風格。

目前在三種主流的Web服務實現方案中,由於REST模式的Web服務與複雜的SOAPXML-RPC對比來說明顯的更加簡潔,愈來愈多的web服務開始採用REST風格設計和實現。例如,Amazon.com提供接近REST風格的Web服務進行圖書查找;雅虎提供的Web服務也是REST風格的。

REST 從資源的角度來觀察整個網絡,分佈在各處的資源由URI肯定,而客戶端的應用經過URI來獲取資源的表形。得到這些表形導致這些應用程序轉變了其狀態。隨着不斷獲取資源的表形,客戶端應用不斷地在轉變着其狀態,所謂表形化的狀態轉變(Representational State Transfer)。

今天不是專門來探討REST的,咱們主要看看WCF是如何實現對REST支持,以及如何使用這種風格的服務。

實現WCF Restful,關鍵在於一個新的Binding方式,也就是WebHttpBinding。因此這種服務,我這裏將其稱爲WebHttp Services。

WebHttp Services是在傳統的SOAP Services基礎上的一個加強,它仍然是基於操做(Operation)的,只不過這些Operation能夠直接經過Uri訪問到,而無需客戶去編寫一個特殊的客戶端。

同時,WebHttp Services提供了兩種不一樣的消息格式,第一種是XML,第二種是Json。這將更加有利於諸如Javascript這種客戶端來訪問服務。

要實現WebHttp,咱們首先要添加一個引用,以下

image

 

而後 ,咱們能夠定義一個特殊的Operation

[OperationContract]
        [WebGet]
        string HelloWorld();

【注意】這裏經過WebGet這個Attribute,聲明該操做是能夠直接在Http訪問中訪問的

下面是該操做的實現

using System;using System.ServiceModel.Activation;namespace WcfService1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.    [AspNetCompatibilityRequirements(RequirementsMode= AspNetCompatibilityRequirementsMode.Required)]     public class Service1 : IService1
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }


     public string HelloWorld() { return "Hello,world"; }     }
}

【備註】該服務必須聲明爲AspNetCompatibility

 

爲了使用該服務支持WebHttpBinding,咱們須要修改配置文件以下(粗體部分是咱們此次添加的)

<?xml version="1.0"?> <configuration>   <system.web>     <compilation debug="true" targetFramework="4.0" />   </system.web>   <system.serviceModel>     <services> <service name="WcfService1.Service1"> <endpoint address="" behaviorConfiguration="WcfService1.Service1AspNetAjaxBehavior" binding="webHttpBinding" contract="WcfService1.IService1" /> </service> </services>     <behaviors>       <endpointBehaviors> <behavior name="WcfService1.Service1AspNetAjaxBehavior"> <enableWebScript /> </behavior> </endpointBehaviors>       <serviceBehaviors>         <behavior name="">           <serviceMetadata httpGetEnabled="true" />           <serviceDebug includeExceptionDetailInFaults="false" />         </behavior>       </serviceBehaviors>     </behaviors>     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"       multipleSiteBindingsEnabled="true" />   </system.serviceModel>  <system.webServer>     <modules runAllManagedModulesForAllRequests="true"/>   </system.webServer>   </configuration>

 

若是是這樣的定義,那麼在瀏覽器中咱們就能夠直接訪問該服務及其操做

image

既然是RESTful,那麼就能夠直接在地址欄像下面這樣訪問

image

咱們發現它的返回值是application/json格式的

image

具體返回的是什麼內容呢?

image

 

也就是說,WebHttp Service默認是返回json格式的數據的,這就很容易在JAVASCRIPT中使用該服務。例如

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="WcfService1._default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">     <title></title>     <script src="jquery-1.4.3.min.js" type="text/javascript"></script>     <script type="text/javascript" language="javascript">
        $(function () {
            $("#btHelloworld").click(function () {
                var uri = "Service1.svc/HelloWorld";
                $.getJSON(uri, null, function (result) {
                    alert(result.d);
                });
            });

        });
    </script> </head> <body>     <form id="form1" runat="server">     <div>     <input type="button" id="btHelloworld"  value="call webhttp Service"/>     </div>     </form> </body> </html>

在頁面中測試的效果以下

image

 

值得注意的是,WebHttp Service除了支持Json格式以外,也支持XML格式,咱們能夠經過修改WebGet這個Attribute的設置來達到目的

[OperationContract]
        [WebGet(ResponseFormat=WebMessageFormat.Xml)]
        string HelloWorld();

 

也能夠經過配置文件的方式來設置(注意粗體部分)

<?xml version="1.0"?> <configuration>   <system.web>     <compilation debug="true" targetFramework="4.0" />   </system.web>   <system.serviceModel>     <services>       <service name="WcfService1.Service1">         <endpoint address="" behaviorConfiguration="WcfService1.Service1AspNetAjaxBehavior"           binding="webHttpBinding" contract="WcfService1.IService1" />       </service>     </services>     <behaviors>       <endpointBehaviors>         <behavior name="WcfService1.Service1AspNetAjaxBehavior">           <enableWebScript />           <webHttp defaultOutgoingResponseFormat="Xml"/>         </behavior>       </endpointBehaviors>       <serviceBehaviors>         <behavior name="">           <serviceMetadata httpGetEnabled="true" />           <serviceDebug includeExceptionDetailInFaults="false" />         </behavior>       </serviceBehaviors>     </behaviors>     <serviceHostingEnvironment aspNetCompatibilityEnabled="true"       multipleSiteBindingsEnabled="true" />   </system.serviceModel>  <system.webServer>     <modules runAllManagedModulesForAllRequests="true"/>   </system.webServer>   </configuration>

若是用XML格式的話,那麼在瀏覽器測試的效果以下

image

image

 

總結:WebHttp Services是在SOAP Services基礎上的一個改進,它不是返回SOAP Evenlope,而是根據須要返回XML或者JSON數據。這樣的設計,目的是讓服務更加易於使用。同時,該服務是WCF Restful的具體實現。

相關文章
相關標籤/搜索