那些年,我们一起学WCF--(7)PerSession实例行为

这一节,大家了解下PerSession实例行为,PerSession表示会话实例行为,当客户端调用服务器后,服务器端会为客户端分配一个新的服务实例,这个实例在服务器端SESSION时间过期后将失效。客户端每调用一次服务,在客户端生成一个新的代理实例,都会产生一个新的会话。

     PerSession实例行为有点类似于ASP.NET中的session,但又些不同.

     在WCF中使用PerSession实例,需要手动设置行为

     [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)], 默认情况下,WCF的实例行为为PerSession

    在WCF中,并不是所有通信协议都可以使用PerSession实例行为的,只有支持会话的通信协议才可以使用PerSession实例,如:NetTcpBinding, NetNamePipeBinding,

wsHttpBinding, wsFederationHttpBinding,wsDualHttpBinding.

    1.PerSession设置

       我们看下代码中怎样设置 persession实例行为。服务器端契约和行为设置

        在契约实现上设置实例行为,在契约上设置会话模式.

[csharp] view plain copy
 
  1. [ServiceContract(SessionMode=SessionMode.Allowed)]  
  2.   public   interface IPerSession  
  3.     {  
  4.        [OperationContract]  
  5.       int AddCountBySession();  
  6.     }  
  7.   
  8.    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]  
  9.   public class PerSessionImpl:IPerSession,IDisposable  
  10.   {  
  11.       private int num;  
  12.       /// <summary>  
  13.       /// 通过 Session模式的方法调用  
  14.       /// </summary>  
  15.       /// <returns></returns>  
  16.       public int AddCountBySession()  
  17.       {  
  18.           num = num + 1;  
  19.           Console.WriteLine("当前值:"+num.ToString()+",时间:"+DateTime.Now.ToString());  
  20.           return num;  
  21.       }  
  22.   
  23.       public void Dispose()  
  24.       {  
  25.           Console.WriteLine("释放实例");  
  26.       }  
  27.   }  

      客户端调用1

[csharp] view plain copy
 
  1. private void button2_Click(object sender, EventArgs e)  
  2.      {  
  3.          //PerSession调用方式  
  4.          ChannelFactory<IPerSession> channelFactory = new ChannelFactory<IPerSession>("WSHttpBinding_IPerSession");  
  5.          IPerSession client = channelFactory.CreateChannel();  
  6.          //同一个客户端实例调用AddCount方法两次,输出的结果一样  
  7.          client.AddCountBySession();  
  8.          client.AddCountBySession();  
  9.      }  

          在上面的客户端调用代码,我们同一个实例调用了两次方法,此时发现服务器端变量的值出现递增,这是因为这两次调用在同一个会话内。

          我们多次点击按钮,会发现每次点击,服务器端的变量值都是从1开始递增,这是因为每次点击按钮都创建了一个新的代理实例,相当于创建了一个新的会话。

   执行结果如下:

             

         我们可以这样理解一个会话,在客户端每生成一个代理实例,就算一个会话,例如上面的 IPerSession client = channelFactory.CreateChannel();实例,就是一个会话,

所以调用了AddCountBySession方法两次,出现变量值递增的情况。

     客户端调用2

     接下来,我们在客户端启动的时候,创建一个全局实例变量。这样连续单击按钮执行多次,服务器端的变量值一直会递增,因为多次执行都是在一个会话内完成的

  

[csharp] view plain copy
 
  1. private void Form1_Load(object sender, EventArgs e)  
  2. {  
  3.     ChannelFactory<IPerSession> channelFactory = new ChannelFactory<IPerSession>("WSHttpBinding_IPerSession");  
  4.     Sessionclient = channelFactory.CreateChannel();  
  5. }  
  6.   
  7. IPerSession Sessionclient;  
  8. private void button3_Click(object sender, EventArgs e)  
  9. {  
  10.     //定义一个全局session实例,进行调用  
  11.     Sessionclient.AddCountBySession();  
  12. }  

  执行结果如下

    
     以上代码我们创建了一个全局实例,多次点击按钮执行,服务器端变量值在同一个会话期内一直递增。

  2.Session时效设置

     PerSession模式的会话时间是有限制的,我们可以手动设置session的会话时间,一旦超过了session的有效时间,session会自动释放。

    可以在服务器端的配置文件中的绑定设置中设置会话时间。

      receiveTimeout="00:00:20" 表示会话时间为20秒,一旦超时,服务器就会关闭会话。

      配置文件如下

[csharp] view plain copy
 
  1. <bindings>  
  2.      <wsHttpBinding>  
  3.        <binding name="WSHttpBinding_IPerSession" closeTimeout="00:01:00"  
  4.                   openTimeout="00:01:00" receiveTimeout="00:00:20" sendTimeout="00:02:00"  
  5.                   bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"  
  6.                   maxBufferPoolSize="524288" maxReceivedMessageSize="65536"  
  7.                   messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"  
  8.                   allowCookies="false">  
  9.          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"  
  10.              maxBytesPerRead="4096" maxNameTableCharCount="16384" />  
  11.          <reliableSession ordered="true" inactivityTimeout="00:10:00"  
  12.              enabled="false" />  
  13.          <security mode="Message">  
  14.            <transport clientCredentialType="Windows" proxyCredentialType="None"  
  15.                realm="" />  
  16.            <message clientCredentialType="Windows" negotiateServiceCredential="true"  
  17.                algorithmSuite="Default" />  
  18.          </security>  
  19.        </binding>  
  20.      </wsHttpBinding>  
  21.    </bindings>  


    通过以上的例子,我们知道Persession的优缺点

       1.通过persession可以设置会话的有效期,保证服务实例在一定范围内可以重复利用。

      缺点:

       1.使用session模式,服务器不能被合理的利用,客户端调用完后,实例不能立刻释放。增加了服务器的压力。

        demo:http://download.csdn.net/detail/zx13525079024/4596356

原文地址:https://www.cnblogs.com/Alex80/p/7678971.html