WCF入門教程之Windows通訊接口

概述

WCF:Windows Communication Foundation ,Windows通信基礎。

SOP:Service Orientation Architechture,面向服務的架構。

WebService是以BasicHttpBing方式運行的WCF。

方案結構:

1、創建解決方案WCFService

依次添加四個項目,如上圖,Client和Hosting為控制臺應用程序,Service和Service.Interface均為類庫。

2、引用關系

  • Service.Interface:定義服務契約(Service Contract)接口,引用WCF核心庫System.ServiceModel.dll;
  • Service:定義服務的項目,由於需要實現具體的服務,而服務契約在Service.Interface中,所以要引用Service.Interface項目;
  • Hosting:服務宿主的控制臺程序,需要引用Service.Interface和Service項目,同時還要引用System.ServiceModel.dll類庫:
  • Client:一個控制臺應用程序的客戶端,需要引用Service.ServiceModel類庫。

一、Contracts協定

一個類庫項目,定義服務契約。

服務契約抽象瞭服務的所有操作,一般契約為接口形式存在。

//服務協定
[ServiceContract(Name = "ICalculator", Namespace = "http://SampleWcfTest")] //webservice描述文件用的portType命名空間
    //CallbackContract =typeof(ICallBack),//雙工時的返回協定
    //ConfigurationName = "Calculator",//配置文件重的服務名
    //ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign,//保護等級
    //SessionMode = SessionMode.Allowed//設置會話的支持模式
public interface ICalculator
{
    //操作協定
    [OperationContract]
    double Add(double n1, double n2);
}

二、Services服務

一個類庫項目,提供對契約的實現。

public class Calculator : ICalculator
{
    public double Add(double n1, double n2)
    {
        double result = n1 + n2;
        Console.WriteLine("Received Add({0},{1})", n1, n2);
        // Code added to write output to the console window.
        Console.WriteLine("Return: {0}", result);
        return result;
    }
}

VS的“WCF服務庫項目”自動生成瞭svc文件和對應的svc.cs文件以及App.config文件,運行此項目,會自動啟動“WCF服務主機”和“WCF測試客戶端”窗口

三、ServiceHost自我服務宿主

一個控制臺項目,通過自我寄宿的方式作為Sevice項目服務的宿主。寄宿進程為ServiceHost1.exe。
服務寄宿的目的是開啟一個進程,為WCF服務提供一個運行環境,並為服務添加一個或者多個終結點,然後暴漏給服務消費者。

WCF服務需要一個運行著的宿主進程,服務寄宿就是給服務指定一個宿主的過程。、

終結點(EndPoint)

WCF采用基於終結點(EndPoint)的通信手段。終結點有地址(Address),綁定(Binding)和契約(Contract)三部分組成,三要素也可以記作:EndPoint=ABC。

一個終結點包含瞭通信所必須的所有信息,具體如下:

  • Address:地址決定瞭服務的位置,解決瞭尋址的問題;
  • Binding:綁定實現瞭通信的所有細節,包括網絡傳輸,消息編碼,以及其他為實現某種功能(比如傳輸安全,可靠消息傳輸,事務等)對消息進行的相應處理。
    WCF中具有一系列的系統定義綁定,比如BasicHttpBinding,WSHttpBinding和NetTcpBinding,WSHttpBinding、NetMsmqBindiing等;
  • Contract:契約是對服務操作的抽象,也是對消息交換模式以及消息結構的定義。

1、編碼方式

//承載服務的宿主
using (ServiceHost selfHost = new ServiceHost(typeof(Calculator)))
{
    try
    {   //添加服務終結點
        selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), new Uri("http://localhost:8000/GettingStarted/"));
        //添加服務元數據行為
        if (selfHost.Description.Behaviors.Find() == null)
        {
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.HttpGetUrl = new Uri("http://localhost:8000/GettingStarted/metadata")
            selfHost.Description.Behaviors.Add(smb);
        }
        selfHost.Open();
        Console.WriteLine("The service is ready.");
        Console.WriteLine("input to terminate service.");
        Console.WriteLine();
        while ("exit" == Console.ReadLine())
        {
            selfHost.Close();
        }
    }
    catch (CommunicationException ex)
    {
        Console.WriteLine(ex.Message);
        selfHost.Abort();
    }
}

2、配置文件方式

打開Hosting項目中的app.config,添加以下代碼即可。

可直接右鍵點擊config文件選擇“編輯WCF配置”菜單,或通過VS的“工具”菜單,選擇“WCF Service配置編輯器”菜單編輯配置文件。

<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <system.serviceModel>
服務
      <service name="Service.CalculatorService" behaviorConfiguration="metadataBehavior">
        <endpoint address="http://127.0.0.1:1111/GettingStarted" binding="wsHttpBinding"  contract="Service.Interface.ICalculator"></endpoint>
      </service>
    </services>
行為
      <serviceBehaviors>
        <behavior name="metadataBehavior">
          <serviceMetadata httpGetEnabled="true"   httpGetUrl="http://127.0.0.1:1111/GettingStarted/metadata"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
   </system.serviceModel>
</configuration>

Hosting代碼修改如下:

    using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
    {
        host.Opened += delegate
          {
              Console.Write("CalculatorService已經啟動,按任意鍵終止服務");
          };
        host.Open();
        Console.Read();
    }

四、IIS宿主

一個Web應用程序,通過IIS寄宿的方式將服務寄宿於IIS中,

寄宿進程為w3wp.exe。WAS激活服務:Window Activation Services。

1、創建WCF服務文件:CalculatorService.svc:

<%@ ServiceHost Sevice=”GettingStarted.CalculatorService” %>

2、配置文件

與app.config相比,web.config無EndPointAddress?服務的地址為.svc所在的地址,默認的元數據為…../CalculatorService.svc?ws…

  <system.serviceModel>
    <services>
      <service name="GettingStarted.CalculatorService" behaviorConfiguration="metadataBehavior" >
        <endpoint address="CalculatorService" binding="wsHttpBinding" contract="Calculator"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="metadataBehavior" >
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

五、實現Rest 風格的web服務

可以使用 WCF REST 編程模型。

默認WebHttpBinding。

在協定的實現方式上添加 WebGet或者WebInvoke屬性

[OperationContract]
[WebInvoke(UriTemplate = "div?x={x}&y={y}")]
long Divide(long x, long y);

[OperationContract]
[WebGet(UriTemplate = "hello?name={name}")]
string SayHello(string name);

舉例2:

[ServiceContract]
public  interface ITestService
{
  [OperationContract]
  [WebInvoke(Method = "POST", UriTemplate = "Test1", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
  string Test1(string userName, string password);
       
  [OperationContract]
  [WebGet(UriTemplate = "Test/{id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
  string Test(string id);        
}

六、使用預配置的主機類WebServiceHost

使用WebServiceHost類

Uri baseAddress = new Uri("http://localhost:8000/");
WebServiceHost svcHost = new WebServiceHost(typeof(CalcService), baseAddress);
try
{
    svcHost.Open();
    Console.WriteLine("Service is running");
    Console.WriteLine("Press enter to quit...");
    Console.ReadLine();

    svcHost.Close();
}
catch (CommunicationException cex)
{
    Console.WriteLine("An exception occurred: {0}", cex.Message);
    svcHost.Abort();
}

3、調用:

http://…/div?x=1&y=2

七、client:一個客戶端

1、使用VS“添加服務引用”生成的CalculatorServiceClient

CalculatorServiceClient基類是System.ServiceModel.ClientBase,該基類封裝瞭ChannelFactory

using (CalculatorServiceClient proxy = new CalculatorServiceClient())
{
    double result = proxy.Add(1, 2);
    Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
}

2、不用添加服務引用,使用ChannelFactory方式

//using (ChannelFactory channelFactory = new ChannelFactory(new WSHttpBinding(), "<a href="http://127.0.0.1:1111/CalculatorService" rel="external nofollow"   target="_blank">http://127.0.0.1</a>:1111/CalculatorService"))//構造函數中指定瞭終結點的ABC三要素,
using (ChannelFactory channelFactory = new ChannelFactory("CalculatorService"))//通過配置文件來進行,對應的為config 文件中終結點的name
{
    ICalculator proxy = channelFactory.CreateChannel();
    using (proxy as IDisposale)
    {
        Console.WriteLine("x+y={2} when x={0} and y={1}", 1, 2, proxy.Add(1, 2));
    }
}

配置文件:

<configuration>
  <system.serviceModel>
    <client>
      <endpoint name="CalculatorService"  address="http://127.0.0.1:1111/CalculatorService"  binding="wsHttpBinding"    contract="Service.Interface.ICalculator"  />
    </client>
  </system.serviceModel>
</configuration>

八、綁定類型

WCF中常用的binding方式:

1. 基於HTTP的綁定

BasicHttpBinding、WSHttpBinding、WSDualHttpBinding和WSFederationHttpBinding選項適合於通過XML Web服務協議提供契約類型。顯然,如果需要使該服務可適用於更多場合(多種操作系統和多種編程語言),這些就是需要關註的綁定,因為所有這些綁定類型都基於XML表示編碼數據並且使用HTTP傳送數據。

在下面清單中,註意到可以在代碼中表示WCF綁定(通過System.ServiceModel名稱空間中的類類型),或者作為在*.config文件中定義的XML屬性表示WCF綁定。

  • BasicHttpBinding:用於綁定符合WS-Basic Profile(WS-I Basic Profile 1.1)的WCF服務。該綁定使用HTTP作為傳送方式,並且使用Text/XML作為默認消息編碼。用於兼容舊的Web ASMX 服務。
    BasicHttpBinding是所有以Web服務為中心的協議中最簡單的協議。特別是,該綁定將確保WCF服務符合由WS-I定義的名為WS-I Basic Profile 1.1的規范。
  • WSHttpBinding:類似於BasicHttpBinding,但是提供瞭更多的Web服務特性。該綁定添加對事務、可靠消息發送和WS-Addressing的支持。
    WSHttpBinding協議不僅集成瞭對WS-*規范(事務、安全性和可靠會話)子集的支持,而且支持使用消息傳輸優化機制(Message Transmission Optimization Mechanism,MTOM)處理二進制數據編碼的能力。
  • WSDualHttpBinding:類似於WSHttpBinding,但是用於與雙向契約結合使用(例如,服務和客戶可以來回發送消息)。該綁定隻支持SOAP安全性,並且需要可靠的消息發送。
    WSDualHttpBinding的主要優點是它添加瞭允許調用者和發送方使用雙向消息發送(duplex messaging)通信的能力,這是一種表示調用者和發送方可以參加雙向會談的流行方法。在選擇WSDualHttpBinding時,可以與WCF發佈/訂閱事件模型建立關聯。
  • WSFederationHttpBinding:安全的和可互操作的綁定,該綁定支持WS-Federation協議,並且允許位於聯盟內的組織有效地驗證和授權用戶
    WSFederationHttpBinding是基於Web服務的協議,在安全性最為重要時就需要使用該協議。該綁定支持WS-Trust、WS-Security和WS-SecureConversation規范,通過WCF CardSpace API表示這些規范。
  • WebHttpBinding:用於通過HTTP(非SOAP)請求提供的服務隊腳本客戶端有用,如ASPNet AJAX。

2. 基於TCP的綁定

如果正在構建一個分佈式系統,該系統涉及使用.NET 3.0/3.5庫配置的一組連網機器(換句話說,所有機器都運行Windows XP、Windows Server 2003或Windows Vista),就可以通過繞開Web服務綁定並選擇使用TCP綁定來增強性能,TCP綁定確保以緊湊二進制格式(而不是XML)編碼所有數據。同樣,在使用下表的的綁定時,客戶和主機必須是.NET應用程序。

  • NetNamedPipeBinding:用於相同機器上不同.NET應用程序之間通信的安全的、可靠的、優化的綁定。
    NetNamedPipeBinding支持事務、可靠的會話和安全的通信,但是它不能夠執行跨機器的調用。如果您正在尋找在相同機器上的WCF應用程序之間推動數據(例如,跨越應用程序的域通信)的最快速方法,NetNamedPipeBinding綁定就是最佳的選擇。
  • NetPeerTcpBinding:為對等(P2P)網絡應用程序提供安全的綁定。
    至於NetPeerTcpBinding,可查閱.NET Framework 3.5 SDK文檔以瞭解關於P2P連網的細節。
  • NetTcpBinding:適合於不同機器上.NET應用程序之間通信的安全的、優化的綁定。
    NetTcpBinding類使用TCP在客戶和WCF服務之間移動二進制數據。前面提及,這將導致比Web服務協議更佳的性能,但是隻限於內部應用程序解決方案。此外,NetTcpBinding支持事務、可靠的會話和安全的通信。

3. 基於MSMQ的綁定

  • MsmqIntegrationBinding:該綁定可用於允許WCF應用程序向已有的MSMQ應用程序發送消息以及從這種應用程序接收消息,這種應用程序使用COM、本地C++或定義在System.Messaging名稱空間中的類型
  • NetMsmqBinding:這個排隊的綁定適合於不同機器上的.NET應用程序之間的通信

註:二進制編碼格式使用TCP、IPC、MSMQ可以獲取最佳性能,但是它是以犧牲互操作性為代價,因為它隻支持WCF到WCF的通信。

到此這篇關於WCF入門教程之Windows通訊接口的文章就介紹到這瞭。希望對大傢的學習有所幫助,也希望大傢多多支持LevelAH。

推薦閱讀: