zoukankan      html  css  js  c++  java
  • 那些年,我们一起学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实例行为。服务器端契约和行为设置

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

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

         客户端调用1

    1. privatevoid 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.      } 
       private void button2_Click(object sender, EventArgs e)
            {
                //PerSession调用方式
                ChannelFactory<IPerSession> channelFactory = new ChannelFactory<IPerSession>("WSHttpBinding_IPerSession");
                IPerSession client = channelFactory.CreateChannel();
                //同一个客户端实例调用AddCount方法两次,输出的结果一样
                client.AddCountBySession();
                client.AddCountBySession();
            }
    

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

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

       执行结果如下:
                

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

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

         客户端调用2

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

      

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

      执行结果如下

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

    2.Session时效设置

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

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

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

          配置文件如下

    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> 
     <bindings>
          <wsHttpBinding>
            <binding name="WSHttpBinding_IPerSession" closeTimeout="00:01:00"
                       openTimeout="00:01:00" receiveTimeout="00:00:20" sendTimeout="00:02: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>
          </wsHttpBinding>
        </bindings>

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

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

          缺点:

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

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

  • 相关阅读:
    java8流处理,不生产博客,做个好博客的搬运工
    java.util.ConcurrentModificationException异常分析
    App登录状态维持
    tomcat没有发布maven项目依赖的本地jar包
    Json对象和Json字符串的区别
    java过滤关键词
    过滤3个字节以上的utf-8字符
    Incorrect string value: 'xF0x9Fx98x84xF0x9F
    SpringBoot配置属性之DataSource
    linux nohup命令使程序在后台运行的方法
  • 原文地址:https://www.cnblogs.com/gjhjoy/p/3487371.html
Copyright © 2011-2022 走看看