WCF初探-26:WCF中的會話

理解WCF中的會話機制

 

  • 在WCF應用程序中,會話將一組消息相互關聯,從而造成對話。會話」是在兩個終結點之間發送的全部消息的一種相互關係。當某個服務協定指定它須要會話時,該協定會指定全部調用(即,支持調用的基礎消息交換)必須是同一對話的一部分。若是某個協定指定它容許使用會話但不要求使用會話,則客戶端能夠進行鏈接,並選擇創建會話或不創建會話。若是會話結束,而後在同一個通道上發送消息,將會引起異常。

  

  • WCF中的會話機制經過設置服務協定(ServiceContract)上的SessionMode的枚舉值來設置服務協定是否要求、容許或拒絕基於會話的綁定。SessionMode的枚舉值有如下三種:
  1. Allowed:容許會話,這是SessionMode的默認值。也就是說在服務協定上沒有采用SessionMode說明時,咱們的服務都是採用的容許會話機制。這種機制說明若是客戶端將基於會話的綁定用於 WCF 服務實現,則服務將創建並使用提供的會話。
  2. Required:要求會話,即全部調用(支持調用的基礎消息交換)都必須是同一個會話的一部分。
  3. NotAllowed:禁止會話,即服務端不會與客戶端進行消息交換。

 

影響WCF中的會話機制其餘屬性機制

 

  • 雖然能夠設置SessionMode的值來控制會話,可是基於會話的綁定支持服務對象與特定會話的默認關聯,例如:
  1. 設置了SessionMode的值爲Required,當採用的綁定爲BasicHttpBinding,由於BasicHttpBinding不支持會話,因此程序仍是報錯。
  2. 對於WSHttpBinding和WS2007HttpBinding,若是咱們將安全模式設置爲None(關閉安全會話)而且關閉可靠會話,他們也沒法提供會話支持。
  3. 對於NetTcpBinding和NetNamedPipeBinding來講,因爲其傳輸類型自己具備支持會話的特性,因此採用了這兩種綁定類型的終結點服務協定的會話模式不能設置爲NotAllowed,即便關閉了安全會話和可靠會話也不行。

 

  • WCF 提供下列類型的基於會話的應用程序行爲:
  1. System.ServiceModel.Channels.SecurityBindingElement 支持基於安全的會話,其中,兩個通訊端採用統一的安全對話。例如:System.ServiceModel.WSHttpBinding 綁定(包含對安全會話和可靠會話的支持)默認狀況下只使用對消息進行加密和數字簽名的安全會話。
  2. System.ServiceModel.NetTcpBinding 綁定支持基於 TCP/IP 的會話,以確保全部消息都由套接字級別的鏈接進行關聯。
  3. System.ServiceModel.Channels.ReliableSessionBindingElement 元素實現 WS-ReliableMessaging 規範,並提供對可靠會話的支持。在可靠會話中,能夠配置消息以按順序傳遞而且只傳遞一次,從而使消息在對話期間即便通過多個節點也能夠確保保密性。
  4. System.ServiceModel.NetMsmqBinding 綁定提供 MSMQ 數據報會話

 

  • 若是使用 WCF 中的默認實例化行爲,則經過同一服務實例來處理 WCF 客戶端對象之間的全部調用。所以,在應用程序級別上,能夠將會話視爲啓用與本地調用行爲類似的應用程序行爲。只要使用默認的服務實例行爲,會話就會在客戶端和服務之間啓用一個類似的行爲。若是服務協定須要或支持會話,則經過設置 IsInitiating 和 IsTerminating 屬性,能夠將一個或多個協定操做標記爲啓動或終止會話。參考WCF初探-15:WCF操做協定

 

WCF中的會話與ASP.NET中的會話

 

  • WCF 會話具備下列主要概念性功能:
  1. 它們由調用應用程序顯式啓動和終止。
  2. 會話期間傳遞的消息按照接收消息的順序進行處理。
  3. 會話將一組消息相互關聯,從而造成對話。該關聯的含義是抽象的。例如,一個基於會話的通道可能會根據共享網絡鏈接來關聯消息,而另外一個基於會話的通道可能會根據消息正文中的共享標記來關聯消息。能夠從會話派生的功能取決於關聯的性質。
  4. 不存在與 WCF 會話相關聯的常規數據存儲區。

 

  • ASP.NET 中的會話由 System.Web.SessionState.HttpSessionState 類提供功能,具備如下特色:
  1. ASP.NET 會話老是由服務器啓動。
  2. ASP.NET 會話本來是無序的。
  3. ASP.NET 會話提供了一種跨請求的常規數據存儲機制。

 

WCF中的使用會話示例說明

 

  • 解決方案以下:

  

  • 工程結構說明以下:
  1. Service:類庫程序,WCF服務端應用程序。服務協定中咱們將SessionMode的值設置爲Required,也就是服務必需要求會話。操做協定中將MethodOne的IsTerminating設置爲true,也就是說在客戶端調用MethodOne後就會關閉會話(注意:設置了IsTerminating爲true的方法是在調用後,服務的會話纔會關閉,因此操做協定MethodOne在客戶端的調用是成功的)。ISampleMethod.cs的代碼以下:
using System.ServiceModel;

namespace Service
{
    [ServiceContract(SessionMode=SessionMode.Required)]
    public interface ISampleMethod
    {
        [OperationContract(IsTerminating=true)]
        string MethodOne(string msg);

        [OperationContract]
        string MethodTwo(string msg);
    }
}

  SampleMethod.cs的代碼以下:html

namespace Service
{
    public class SampleMethod:ISampleMethod
    {
        public string MethodOne(string msg)
        {
            return "You called MethodOne return message is: " + msg;
        }

        public string MethodTwo(string msg)
        {
            return "You called MethodTwo return message is: " + msg;
        }
    }
}

  2.  Host:控制檯應用程序,服務承載程序。添加對程序集Service的引用,完成如下代碼,寄宿服務。Program.cs代碼以下:安全

  
using System;
using System.ServiceModel;
using Service;

namespace Host
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(SampleMethod)))
            {
                host.Opened += delegate { Console.WriteLine("服務已經啓動,按任意鍵終止!"); };
                host.Open();
                Console.Read();
            }
        }
    }
}
View Code

  App.config代碼以下:服務器

  
<?xml version="1.0"?>
<configuration>
    <system.serviceModel>

        <services>
            <service name="Service.SampleMethod" behaviorConfiguration="mexBehavior">
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:1234/SampleMethod/"/>
                    </baseAddresses>
                </host>
                <endpoint address="" binding="wsHttpBinding" contract="Service.ISampleMethod" />
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            </service>
        </services>

        <behaviors>
            <serviceBehaviors>
                <behavior name="mexBehavior">
                    <serviceMetadata httpGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>
View Code

  咱們經過svcutil.exe工具生成客戶端代理類和客戶端的配置文件網絡

  svcutil.exe是一個命令行工具,位於路徑C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin下,ide

  咱們能夠經過命令行運行該工具生成客戶端代理類工具

  在運行中輸入cmd打開命令行,輸入 cd C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Binui

  輸入svcutil.exe /out:f:\ SampleMethodClient.cs /config:f:\App.config http://localhost:1234/SampleMethod加密

  

   3.  Client:控制檯應用程序,客戶端調用程序。將生成的SampleMethodClient.cs和App.config複製到Client的工程目錄下,完成客戶端調用代碼。spa

    爲驗證WCF的會話特色,咱們將客戶端的調用分爲如下幾種狀況:命令行

  • 實例化客戶端代理類對象Client1,調用MethodOne和MethodTwo,因爲MethodOne的IsTerminating設置爲true,因此在客戶端Client1調用完MethodOne後會話就會關閉,因此MethodTwo調用不會成功。Client1在調用MethodOne的時候,會話機制會自動啓動。因爲話期間傳遞的消息按照接收消息的順序進行處理,因此在Client1調用MethodOne後再次調用MethodOne也不會成功。即在調用MethodOne方法後的調用都不會成功。參考代碼以下:
using System;
namespace Client{
    class Program{
        static void Main(string[] args){
            try{
                SampleMethodClient client1 = new SampleMethodClient();
                Console.WriteLine(client1.MethodOne("MethodOne"));
                Console.WriteLine(client1.MethodTwo("MethodTwo"));
            }
       catch (Exception ex){ Console.WriteLine(ex.Message); } finally{ Console.Read(); } }}}

  運行結果以下:

  

  • 實例化客戶端代理類對象Client1和Client2,在兩個實例化對象中分別調用MethodOne,能夠看到調用成功,由於默認的服務實例化模型(InstanceContextMode)採用PerSession,即每一個服務實例都各自建立了一個會話通道,當Client1調用MethodOne後會話關閉,但Client2的會話通道並無關閉,因此仍是能夠調用MethodOne。在調用MethodOne後兩個會話都會關閉,這是因爲MethodOne的IsTerminating設置爲true的結果。參考代碼以下: 
    try
      {
           SampleMethodClient client1 = new SampleMethodClient();
           Console.WriteLine(client1.MethodOne("First Called MethodOne"));

           SampleMethodClient client2 = new SampleMethodClient();
           Console.WriteLine(client2.MethodOne("Second Called MethodOne"));
      }
      catch (Exception ex)
      {
           Console.WriteLine(ex.Message);
      }
      finally
      {
           Console.Read();
      }

  運行結果以下:

  

  • 因爲本示例採用的是wsHttpBinding綁定機制,能夠把客戶端生成的配置文件的可靠會話(reliableSession) enabled設置爲false,安全會話(security)的mode設置爲none.這樣即便服務協定採用了會話支持,可是因爲綁定機制的影響,因此會話通道不會創建成功。將客戶端配置文件中的
<security mode="Message">
     <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
     <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" />
</security>

  替換爲

<security mode="None"/>

  運行結果以下:

  

 

相關文章
相關標籤/搜索