<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Windows Communication Foundation入門(Part Two)

      三、WCF的技術要素
      作為基于SOA(Service Oriented Architecture)的一個框架產品,WCF最重要的就是能夠快捷的創建一個服務(Service)。如下圖所示,一個WCF Service由下面三部分構成:
       

      wcf06.gif


      1、Service Class:一個標記了[ServiceContract]Attribute的類,在其中可能包含多個方法。除了標記了一些WCF特有的Attribute外,這個類與一般的類沒有什么區別。
      2、Host(宿主):可以是應用程序,進程如Windows Service等,它是WCF Service運行的環境。
      3、Endpoints:可以是一個,也可以是一組,它是WCF實現通信的核心要素。

      WCF Service由一個Endpoints集合組成,每個Endpoint就是用于通信的入口,客戶端和服務端通過Endpoint交換信息,如下圖所示:
       

      wcf07.gif

      從圖中我們可以看到一個Endpoint由三部分組成:Address,Binding,Contract。便于記憶,我們往往將這三部分稱為是Endpoint的ABCs。

      Address是Endpoint的網絡地址,它標記了消息發送的目的地。Binding描述的是如何發送消息,例如消息發送的傳輸協議(如TCP,HTTP),安全(如SSL,SOAP消息安全)。Contract則描述的是消息所包含的內容,以及消息的組織和操作方式,例如是one-way,duplex和request/reply。所以Endpoint中的ABCs分別代表的含義就是:where,how,what。當WCF發送消息時,通過address知道消息發送的地址,通過binding知道怎樣來發送它,通過contract則知道發送的消息是什么。

      在WCF中,類ServiceEndpoint代表了一個Endpoint,在類中包含的EndpointAddress,Binding,ContractDescription類型分別對應Endpoint的Address,Binding,Contract,如下圖:
       

      wcf08.gif

      EndpointAddress類又包含URI,Identity和可選的headers集合組成,如下圖:
       

      wcf09.gif


      Endpoint安全的唯一性識別通常是通過其URI的值,但為了避免一些特殊情況造成URI的重復,又引入了Identity附加到URI上,保證了Endpoint地址的唯一性。至于可選的AddressHeader則提供了一些附加的信息,尤其是當多個Endpoint在使用同樣的URI地址信息時,AddressHeader就非常必要了。

      Binding類包含Name,Namespace和BindingElement集合,如下圖:
       

      wcf10.gif


      Binding的Name以及Namespace是服務元數據(service’s metadata)的唯一標識。BindingElement描述的是WCF通信時binding的方式。例如,SecurityBindingElement表示Endpoint使用SOAP消息安全方式,而ReliableSessionBindingElement表示Endpoint利用可信賴消息確保消息的傳送。TcpTransportBindingElement則表示Endpoint利用TCP作為通信的傳輸協議。每種BindingElement還有相應的屬性值,進一步詳細的描述WCF通信的方式。

      BindingElement的順序也非常重要。BindingElement集合通常會創建一個用于通信的堆棧,其順序與BindingElement集合中元素順序一致。集合中最后一個binding element對應于通信堆棧的底部,而集合中的第一個binding element則對應于堆棧的頂端。入消息流的方向是從底部經過堆棧向上,而出消息流的方向則從頂端向下。因此,BindingElement集合中的binding element順序直接影響了通信堆棧處理消息的順序。幸運的是,WCF已經提供了一系列預定義的Binding,能夠滿足大多數情況,而不需要我們自定義Binding,殫精竭慮地考慮binding element的順序。

      Contract是一組操作(Operations)的集合,該操作定義了Endpoint通信的內容,每個Operation都是一個簡單的消息交換(message exchange),例如one-way或者request/reply消息交換。

      類ContractDescription用于描述WCF的Contracts以及它們的操作operations。在ContractDescription類中,每個Contract的operation都有相對應的OperationDescription,用于描述operation的類型,例如是one-way,還是request/reply。在OperationDescription中還包含了MessageDecription集合用于描述message。

      在WCF編程模型中,ContractDescription通常是在定義Contract的接口或類中創建。對于這個接口或類類型,標記以ServiceContractAttribute,而其Operation方法則標記以OperationContractAttribute。當然我們也可以不利用CLR的attribute,而采用手工創建。

      與Binding一樣,每個Contract也包含有Name和Namespace,用于在Service的元數據中作為唯一性識別。此外,Contract中還包含了ContractBehavior的集合,ContractBehavior類型可以用于修改或擴展contract的行為。類ContractDescription的組成如下圖所示:
       

      wcf11.gif

      正如在ContractDescription中包含的IContractBehavior一樣,WCF專門提供了行為Behavior,它可以對客戶端和服務端的一些功能進行修改或者擴展。例如ServiceMetadataBehavior用于控制Service是否發布元數據。相似的,security behavior用于控制安全與授權,transaction behavior則控制事務。

      除了前面提到的ContractBehavior,還包括ServiceBehavior和ChannelBehaivor。ServiceBehavior實現了IServiceBehavior接口,ChannelBehaivor則實現了IChannleBehavior接口。

      由于WCF需要管理的是服務端與客戶端的通信。對于服務端,WCF提供了類ServiceDescription用于描述一個WCF Service,;而針對客戶端,WCF管理的是發送消息時需要使用到的通道Channel,類ChannelDescription描述了這樣的客戶端通道。

      ServiceDescription類的組成如下圖所示:
       

      wcf12.gif

      我們可以利用代碼的方式創建ServiceDescription對象,也可以利用WCF的Attribute,或者使用工具SvcUtil.exe。雖然可以顯式的創建它,但通常情況下,它會作為運行中的Service一部分而被隱藏于后(我在后面會提到)。

      ChannelDescription類的組成與ServiceDescription大致相同,但它僅僅包含了一個ServiceEndpoint,用于表示客戶端通過通道通信的目標Endpoint。當然,施加到ChannelDescription的Behavior也相應的為IChannelBehavior接口類型,如圖所示:
       

      wcf13.gif

      定義一個WCF Service非常簡單,以Hello World為例,定義的Service可能如下:
      using System.ServiceModel
      [ServiceContract]
      public class HelloWorld
      {
          [OperationContract]
       public void Hello()
       {
        Console.WriteLine(“Hello World!”);
       }
      }

      System.ServiceModel是微軟為WCF提供的一個新的類庫,以用于面向服務的程序設計。在開發WCF應用程序時,需要先添加對System.ServiceModel的引用。WCF中的大部分類和接口也都是在命名空間System.ServiceModel下。

      我們為HelloWorld類標記了[ServiceContract],這就使得該類成為了一個WCF Service,而其中的方法Hello()則因為標記了[OperationContract],而成為該Service的一個Operation。

      不過WCF推薦的做法是將接口定義為一個Service,這使得WCF Service具有更好的靈活性,畢竟對于一個接口而言,可以在同時有多個類實現該接口,這也就意味著可以有多個Service Contract的實現。那么上面的例子就可以修改為:
      [ServiceContract]
      public interface IHello
      {
       [OperationContract]
       void Hello();
      }

      而類HelloWorld則實現該IHello接口:
      public class HelloWorld:IHello
      {
       public void Hello()
       {
        Console.WriteLine(“Hello World!”);
       }
      }

      注意在實現了IHello接口的類HelloWorld中,不再需要在類和方法中標注ServiceContractAttribute和OperationContractAttribute了。

      前面我已經提過,一個WCF Service必須有host作為它運行的環境。這個host可以是ASP.Net,可以是Windows Service,也可以是一個普通的應用程序,例如控制臺程序。下面就是一個Host的實現:
      using System.ServiceModel
      public class HostApp
      {
       static void Main(string[] args)
       {
        ServiceHost host = new ServiceHost(typeof(HelloWorld), new Uri(“http://localhost:8080/HelloService”));
        host.AddServiceEndpoint(typeof(IHello), new BasicHttpBinding(),”Svc”);
        host.Open();
        Console.WriteLine(“Start Your Service.”);
        Console.ReadKey();
        host.Close();
       }
      }

      在這個HostApp中,我們為HelloWorld創建了一個ServiceHost對象。通過它就可以創建WCF運行時(Runtime),WCF Runtime是一組負責接收和發送消息的對象。ServiceHost可以創建SerivceDescription對象,利用SerivceDescription,SercieHost為每一個ServiceEndpoint創建一個EndpointListener。ServiceHost的組成如下圖:
       

      wcf14.gif


      EndpointListener偵聽器包含了listening address,message filtering和dispatch,它們對應ServiceEndpoint中的EndpointAddress,Contract和Binding。在EndpointListener中,還包含了一個Channel Stack,專門負責發送和接收消息。

      注意在創建ServiceHost時,傳遞的type類型參數,不能是interface。因此,我在這里傳入的是typeof(HelloWorld)。ServiceHost類的AddServiceEndpoint()方法實現了為Host添加Endpoint的功能,其參數正好是Endpoint的三部分:Address,Bingding和Contract。(此時的IHello即為ServiceContract,其方法Hello為OperationContract)。

      ServiceHost的Open()方法用于創建和打開Service運行時,而在程序結束后我又調用了Close()方法,來關閉這個運行時。實際上以本例而言,該方法可以不調用,因為在應用程序結束后,系統會自動關閉該host。但作為一種良好的編程習慣,WCF仍然要求顯式調用Close()方法,因為Service運行時其本質是利用Channel來完成消息的傳遞,當打開一個Service運行時的時候,系統會占用一個Channel,調用完后,我們就需要釋放對該通道的占用。當然我們也可以用using語句來管理ServiceHost資源的釋放。

      定義好了一個WCF Service,并將其運行在Host上后,如何實現它與客戶端的通信呢?典型的情況下,服務端與客戶端均采用了Web Service Description Language(WSDL),客戶端可以通過工具SvcUtil.exe生成對應于該WCF Service的Proxy代碼,以完成之間的消息傳遞,如圖所示:
       

      wcf15.gif

      SvcUtil.exe是由WinFx Runtime Component SDK所提供的,如果安裝SDK正確,可以在其中找到該應用工具。生成客戶端Proxy代碼的方法很簡單,首先需要運行服務端Service。然后再命令行模式下運行下面的命令:
      SvcUtil http://localhost:8080/HelloService

      這樣會在當前目錄下產生兩個文件output.cs和output.config。前者最主要的就是包含了一個實現了IHello接口的Proxy對象,這個代理對象名為HelloProxy,代碼生成的結果如下:
      [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
      public partial class HelloProxy : System.ServiceModel.ClientBase<IHello>, IHello
      {   
          public HelloProxy()
          {
          }   
          public HelloProxy(string endpointConfigurationName) :
                  base(endpointConfigurationName)
          {
          }   
          public HelloProxy(string endpointConfigurationName, string remoteAddress) :
                  base(endpointConfigurationName, remoteAddress)
          {
          }   
          public HelloProxy(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
                  base(endpointConfigurationName, remoteAddress)
          {
          }   
          public HelloProxy(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
                  base(binding, remoteAddress)
          {
          }   
          public void Hello()
          {
              base.InnerProxy.Hello();
          }
      }
      (注:本程序在WinFx 2006 February CTP版本下運行通過)

      至于后者,則是WCF Service的配置信息,主要包含的是Endpoint中Address,Binding以及Contract的配置(在后續文章我會詳細介紹)。

      現在客戶端就可以直接使用HelloProxy對象,來完成與服務端的通信了:
      public class ClientApp
      {
       static void Main(string[] args)
          {
              using (HelloProxy proxy = new HelloProxy())
        {
               proxy.Hello();
              }
      Console.ReadKey();
          }
      }

      除了可以使用SvcUtil工具產生客戶端代碼,同樣我們也可以利用代碼的方式來完成客戶端。客戶端在發送消息給服務端時,其通信的基礎是Service的Endpoint,WCF提供了System.ServiceModel.Description.ServiceEndpoint類,通過創建它來實現兩端的通信。在前面,我還提到“對于客戶端而言,WCF管理的是發送消息時需要使用到的通道Channel”,為此,WCF提供了ChannelFactory(其命名空間為System.ServiceModel.Channel),專門用于創建客戶端運行時(runtime)。ChannelFactory與ServiceHost相對應,它可以創建ChannelDescription對象。與服務端ServiceHost不同的是,客戶端并不需要偵聽器,因為客戶端往往是建立連接的“發起方”,并不需要偵聽進來的連接。因此客戶端的Channel Stack會由ChannelDescription創建。

      ChannelFactory和ServiceHost都具有Channel Stack,而服務端與客戶端的通信又是通過channel來完成,這就意味著,利用ChannelFactory,客戶端可以發送消息到服務端。而客戶端本身并不存在Service對象,因此該Service的Proxy,是可以通過Channel來得到的。所以客戶端的代碼可以修改如下:
      using System.ServiceModel;
      using System.ServiceModel.Description;
      using System.ServiceModel.Channel

      public class ClientApp
      {
       static void Main(string[] args)
          {
              ServiceEndpoint httpEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(IHello)), new BasicHttpBinding(), new EndpointAddress(“http://localhost:8080/HelloService/Svc”));

        using (ChannelFactory<IHello> factory = new ChannelFactory<IHello>(httpEndPoint))
        {
         //創建IHello服務的代理對象;
         IHello service = factory.CreateChannel();
         service.Hello();
        }
        Console.ReadKey();
          }
      }
      (注:本程序在WinFx 2006 February CTP版本下運行通過)

      對于上面的代碼,我們有兩點需要注意:
      1、采用這種方式,前提條件是客戶端能夠訪問IHello接口。這也印證了之前我所敘述的最好使用interface來定義Service的好處。此外,為了保證部署的方便,有關Service的interface最好單獨編譯為一個程序集,便于更好的部署到客戶端。
      2、客戶端必須知道服務端binding的方式以及address。

      對于服務端而言,我們也可以直接在瀏覽器中打開該Service,在地址欄中輸入http://localhost:8080/HelloService,如下圖:
       

      wcf16.gif

      點擊鏈接:http://localhost:8080/HelloService?wsdl,我們可以直接看到HelloService的WSDL。注意到在這里我并沒有使用IIS,實際上WCF內建了對httpsys的集成,允許任何應用程序自動成為HTTP listener。

      參考:
      1、David Chappell,Introducing Windows Communication Foundation
      2、Aaron Skonnard,Learn The ABCs Of Programming Windows Communication Foundation
      3、Microsoft Corporation,Windows Communication Foundation Architecture Overview

      <未完待續>

      posted @ 2006-04-10 08:37  張逸  閱讀(10796)  評論(6)    收藏  舉報
      主站蜘蛛池模板: 成人午夜大片免费看爽爽爽| 国产成人精品无人区一区| 亚洲中文字幕无码专区| 国产午夜福利精品视频| 成人午夜污一区二区三区| 少妇被多人c夜夜爽爽av| 亚洲国产日韩欧美一区二区三区| 无码人妻精品一区二区三区下载| 国产精品午夜无码AV天美传媒 | 中文字幕国产精品资源| 国产精品成人无码久久久| 精品精品久久宅男的天堂| 亚洲久悠悠色悠在线播放| 久久国产一区二区三区| 五月婷婷开心中文字幕| 横峰县| 国产乱人伦真实精品视频| 国产日韩精品一区在线不卡| 国产成人理论在线视频观看| аⅴ天堂国产最新版在线中文| 国产午夜亚洲精品国产成人 | 男女男免费视频网站国产| 精品无码三级在线观看视频 | 亚洲肥老太bbw中国熟女| 国产女人18毛片水真多1| 久久国产自拍一区二区三区| 丰满人妻被黑人连续中出| 依依成人精品视频在线观看| 免费看黄色亚洲一区久久| 51午夜精品免费视频| 亚洲一本二区偷拍精品| 精品国产一区av天美传媒| 一区二区三区久久精品国产| 精品婷婷色一区二区三区| 资源在线观看视频一区二区| 亚洲熟妇乱色一区二区三区| 欧美黑人乱大交| 欧美国产日产一区二区| 亚洲欧美日韩在线码| 国产一区二区在线有码| 午夜福制92视频|