WCF学习之实例类型

来源:互联网 发布:sql count 两列 编辑:程序博客网 时间:2024/05/18 03:56
 准备技术:

  WCF服务契约、数据契约等基础知识

  Donet基本开发

  内容概要:

  三种实例激活类型

  单调服务

  会话服务

  单例服务

  实例类型

  WCF支持三种实例类型:PerCall、PerSession、Single。PerCall就是单调服务会为每次客户端的请求去分配一个新的服务实例;PerSession会为每次客户端连接分配一个实例;Single所有的客户端会去共享一个相同的服务实例。

  WCF是通过ServiceBehavior特性中的InstanceContextMode属性来告诉服务实例采用那种类型,InstanceContextMode属性是一个InstanceContextMode的枚举类型,InstanceContextMode有三个成员:PerCall(单调),PerSession(会话),Single(单例)。

  单调服务

  单调服务实例只存在于客户端的调用过程中,每次客户端的一个请求就会获得一个新的服务实例。也就说我们在客户端的每次调用一个方法时都会去重新返回一个新的实例给我们。下面我们看一个配置为单调服务实例的例子。

  首先看我们的服务契约很简单IBehaverContract.cs:

[ServiceContract(Name="IBehaverContract")]
  publicinterfaceIBehaverContract
  {
    [OperationContract(Name="TestBehavor")]
    stringTestBehavor();
}

  我们的服务实例BehaverContract.cs为:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCal)]
  publicclassBehaverContract:ServiceContracts.IBehaverContract,IDisposable
  {
    privateint_Count=0;
    publicBehaverContract()
    {
      Console.Write("BehaverContract.BehaverContract()n");
    }
    publicstringTestBehavor()
    {
      _Count++;
      returnString.Format("Thenumberis:{0}",_Count);
    }
    publicvoidDispose()
    {
      Console.Write("BehaverContract.Dispose()n");
    }
}

我们在客户端调用:

stringstrResult=proxy.TestBehavor();
stringstrResult2=proxy.TestBehavor();
Console.Write(strResult+"n");
Console.Write(strResult2);

  结果如图:

  WCF学习之实例类型< p>

WCF学习之实例类型<>

  会话服务

  如果服务被配置为会话服务类型,那么客户端为该服务创建一个新的代理时,就会获得一个新的而且是自己专有的,跟其他实例无关的服务实例。这种模式非常像经典的c/s模式,该实例一直到客户端不在需要使用时才会去释放。PerSession模式也就是相当于remoting中的客户端激活模式。

  在配置私有会话时候,我们需要在服务上配置InstanceContextMode为PerSession,PerSession也是InstanceContextMode属性的默认值。配置了这样的属性时,并不能确保我们的服务就是私有会话的,因为私有会话模式需要维持某一个客户端到服务器端的状态,所以需要客户端到服务端的连接是持久的。那么Http协议的无连接就不能维持私有会话了,如果要基于Http的传输WCF提供了wsHttpBinding来模仿一个持久的传输。

在传输层的会话的同时,契约的配置也是需要的,因为在运行时WCF需要知道服务是否启用了会话。通过ServiceContract的SessionMode属性,我们可以来设定我们的契约是否支持会话。

  SessionMode枚举有三个成员:Allowed、Required、NotAllowed。SessionMode属性的默认值为SessionMode. Allowed。当我们设置为Allowed时只能代表是允许,只有当绑定是一个传输层会话时才能采用会话服务的执行。SessionMode.Required要求必须使用传输层会话。SessionMode.NotAllowed禁止使用传输层会话,也就不能使用应用层会话了,也就是说即使我们将InstanceContextMode属性配置为InstanceContextMode.PerSession时,它总会采用PerCall去执行。

  我们还看刚才那个的那个例子,只是把相应的配置给修改下。首先我们将服务契约的SessionMode设置为SessionMode.Requried:

[ServiceContract(Name="IBehaverContract",SessionMode=SessionMode.Required)]
publicinterfaceIBehaverContract

  然后我们将服务实例设置为:InstanceContextMode.PerSession:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
publicclassBehaverContract:ServiceContracts.IBehaverContract,IDisposable

  同时我们需要在宿主中的绑定配置为支持传输层会话的:

<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
 <system.serviceModel>
  <services>
   <servicename="Service.BehaverContract"behaviorConfiguration="behavior">
    <endpointbinding="wsHttpBinding"
         contract="ServiceContracts.IBehaverContract"
         address="BehaverContract"
         bindingConfiguration="HttpSession">
    </endpoint>
    <host>
     <baseAddresses>
      <addbaseAddress="http://localhost:8000"/>
     </baseAddresses>
    </host>
   </service>
  </services>
  <behaviors>
   <serviceBehaviors>
    <behaviorname="behavior">
     <serviceMetadatahttpGetEnabled="true"/>
    </behavior>
   </serviceBehaviors>
  </behaviors>
  <bindings>
   <wsHttpBinding>
    <bindingname="HttpSession">
     <reliableSessionenabled="true"/>
    </binding>
   </wsHttpBinding>
  </bindings>
 </system.serviceModel>
</configuration>

 客户端的调用还是一样的,我们看到如下的结果:

WCF学习之实例类型<>

WCF学习之实例类型<>

原创粉丝点击