WCF一步一步往前爬(六)

來源:互聯網
上載者:User

 wcf中會話模式(PerSession)的應用。

PerSession工作方式:

  • 用戶端建立代理對象(Proxy)
  • 用戶端第一次調用代理對象的一個契約操作,代理對象將其調用請求傳遞給服務宿主
  • 宿主程式建立新的服務物件,並執行請求操作,如果有必要,返回用戶端應答
  • 用戶端再次發出叫用作業的請求,宿主會先判斷是否已有建立好的會話,如果存在,則不需要再建立新的服務物件,直接使用老對象即可。
  • 在時間達到指定要求或者因一些特殊原因,會話會到期,此時服務物件銷毀。

    對於會話模式,basicHttpBinding是不支援的,所以如果是發布到iis,終結點的綁定不能是basicHttpBinding,可以選擇netTcpBinding和ws2007HttpBinding

    下面看看例子:

    服務端:

    namespace LifeCycleService
    {
    // 注意: 使用“重構”菜單上的“重新命名”命令,可以同時更改代碼和設定檔中的介面名“IService”。
    [ServiceContract(SessionMode= SessionMode.Required)]
    public interface ILifeCycleService
    {
    [OperationContract]
    string DoWork();

    [OperationContract]
    string GetInstance();
    }
    }

    namespace LifeCycleService
    {
    // 注意: 使用“重構”菜單上的“重新命名”命令,可以同時更改代碼、服務和設定檔中的類名“Service”。
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    //[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class LifeCycleServiceImpl : ILifeCycleService
    {
    // 服務執行個體的個數
    static int instance;
    int times = 0;

    // 建構函式,初始化callCount,並將服務執行個體的個數加1
    public LifeCycleServiceImpl()
    {
    instance++;
    System.Diagnostics.Debug.WriteLine("Create a new instance: " + instance.ToString() + "");
    }

    public string GetInstance()
    {
    string outstr = string.Format("Current Instance is {0}", instance);
    return outstr;
    }

    // 被調用的函數,每次被調用callCount加1
    public string DoWork()
    {
    times++;
    string OutStr = string.Format("DoWork() is called by Instance {0}--Times:{1}", OperationContext.Current.SessionId, times);
    return OutStr;
    }
    }
    }

    <%@ ServiceHost Language="C#" Debug="true" Service="LifeCycleService.LifeCycleServiceImpl" CodeBehind="~/App_Code/LifeCycleService.cs" %>

    <system.web>
    <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.serviceModel>

    <services>

    <service name="LifeCycleService.LifeCycleServiceImpl">
    <endpoint address="http://lisheng/LifeCycleService/LifeCycleService.svc" binding="ws2007HttpBinding"
    name="LifeCycle_ws2007HttpBinding" contract="LifeCycleService.ILifeCycleService" />

    <endpoint address="net.tcp://lisheng/LifeCycleService/LifeCycleService.svc" binding="netTcpBinding"
    name="LifeCycle_netTcpBinding" contract="LifeCycleService.ILifeCycleService" />
    </service>

    </services>

    <behaviors>
    <serviceBehaviors>
    <behavior>
    <!-- 為避免泄漏中繼資料資訊,請在部署前將以下值設定為 false 並刪除上面的中繼資料終結點 -->
    <serviceMetadata httpGetEnabled="true"/>
    <!-- 要接收故障異常詳細資料以進行調試,請將以下值設定為 true。在部署前設定為 false 以避免泄漏異常資訊-->
    <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
    </serviceBehaviors>
    </behaviors>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="false">
    <serviceActivations>
    <add relativeAddress="LifeCycleService.svc" service="LifeCycleService.LifeCycleServiceImpl" />
    </serviceActivations>
    </serviceHostingEnvironment>

    </system.serviceModel>
    <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>

    </configuration>

    用戶端:

    static void Main(string[] args)
    {
    Console.WriteLine("When the service is ready, press any key to countinue!");
    Console.ReadKey(true);

    using (LifeCycleServiceClient client1 = new LifeCycleServiceClient("LifeCycle_netTcpBinding"))
    {
    client1.Open();
    Console.WriteLine(string.Format("=============start: {0}================", client1.GetInstance()));
    for (int i = 1; i < 4; i++)
    {
    Console.WriteLine(client1.DoWork());
    }

    Console.WriteLine(string.Format("=============end: {0}================", client1.GetInstance()));
    }
    Console.WriteLine();

    using (LifeCycleServiceClient client2 = new LifeCycleServiceClient("LifeCycle_ws2007HttpBinding"))
    {
    client2.Open();
    Console.WriteLine(string.Format("=============start: {0}================", client2.GetInstance()));
    for (int i = 1; i < 4; i++)
    {
    Console.WriteLine(client2.DoWork());
    }
    Console.WriteLine(string.Format("=============end: {0}================", client2.GetInstance()));
    }
    Console.ReadKey(true);

    }

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <system.serviceModel>
    <bindings>
    <netTcpBinding>
    <binding name="LifeCycle_netTcpBinding" closeTimeout="00:01:00"
    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
    transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
    hostNameComparisonMode="StrongWildcard" listenBacklog="10"
    maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
    maxReceivedMessageSize="65536">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <reliableSession ordered="true" inactivityTimeout="00:10:00"
    enabled="false" />
    <security mode="Transport">
    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
    <message clientCredentialType="Windows" />
    </security>
    </binding>
    </netTcpBinding>
    <ws2007HttpBinding>
    <binding name="LifeCycle_ws2007HttpBinding" closeTimeout="00:01:00"
    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
    allowCookies="false">
    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    <reliableSession ordered="true" inactivityTimeout="00:10:00"
    enabled="false" />
    <security mode="Message">
    <transport clientCredentialType="Windows" proxyCredentialType="None"
    realm="" />
    <message clientCredentialType="Windows" negotiateServiceCredential="true"
    algorithmSuite="Default" />
    </security>
    </binding>
    </ws2007HttpBinding>
    </bindings>
    <client>
    <endpoint address="http://lisheng/LifeCycleService/LifeCycleService.svc"
    binding="ws2007HttpBinding" bindingConfiguration="LifeCycle_ws2007HttpBinding"
    contract="LifeCycleService.ILifeCycleService" name="LifeCycle_ws2007HttpBinding">
    <identity>
    <servicePrincipalName value="host/lisheng" />
    </identity>
    </endpoint>
    <endpoint address="net.tcp://lisheng/LifeCycleService/LifeCycleService.svc"
    binding="netTcpBinding" contract="LifeCycleService.ILifeCycleService"
    name="LifeCycle_netTcpBinding" />
    </client>
    </system.serviceModel>
    </configuration>

    看看另外兩種模式工作方式:

    PerCall:

    1. 用戶端建立代理對象(Proxy)
    2. 用戶端調用代理對象的一個契約操作,代理對象將其傳遞給服務宿主程式。
    3. 宿主應用程式建立一新的服務契約對象,並且執行請求操作
    4. 在執行完請求操作後,如果要求有應答,那麼服務契約會給代理對象一個應答,然後銷毀自己(如果實現了IDisposable,則調用Dispose())。

    Single :

    1. 服務端啟動,同時建立服務物件
    2. 用戶端通過代理調用契約操作
    3. 第一步中建立的服務物件接受請求 ,並執行操作,進行必要的應答
    4. 第一步建立的服務物件將一直保留
    5. 服務關閉,第一步建立的對象銷毀
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.