zoukankan      html  css  js  c++  java
  • WCF 第五章 会话级别的实例

    会话在分布式应用程序中广泛用于维护每个用户的状态。在站点或者基于站点的应用中,将每个用户的状态存储于会话中很常见。这这些情况中,用户和会话间有一个1:1比例。WCF以一个类似的概念支持服务。使用InstanceContextMode.PerSession设置,WCF可以直接为每个会话创建一个服务实例。

    提示 实例会话与可信赖会话不同

    Per-Session服务实例不应该与另一个WCF特性弄混,可信赖会话。这个特性,实现了WS-RM规范,用来确定在扩媒介的不同终结点间的可信赖的,顺序的消息传输。它与并发或者对象创建行为没有任何关系。

      为了实现Per-session服务实例,必须做两件事:在契约层允许会话,在服务层允许会话。

      在契约层,会话通过在服务契约上使用SessionMode行为实现。行为的值可以是Allowed,NotAllowed或者Required.尽管会话在契约层确定,它们事实上是由绑定元素在信道层确认。因此,当服务首先启动时,契约行为确认契约和信道是兼容的。例如,如果信道需要会话,但是一个使用的绑定不支持会话(比如basicHttpBinding),那么契约上的会话需求就不能被满足,所以当服务启动时契约行为会抛出一个异常。

      在服务层,会话通过为InstanceContextMode.Persession设置InstanceContextMode行为属性来启用。这指导WCF为连接到服务端的每个独一无二的会话创建一个服务实例。InstanceContextMode的其他选项是PerCall或者Single.PerCall为每次调用创建一个新的实例而Single为所有调用者仅维护一个实例。

      列表5.5显示了使用InstanceContextMode.PerSession行为的服务端代码。InstanceContextMode行为指导WCF为每个独立的会话创建一个服务实例。除了返回一个stcok price,代码也跟踪记录它被调用了多少次。因为InstanceContextMode被设置成PerSession,客户端能看见它在会话中调用服务的次数,总的数目并不是服务调用的次数。如果InstanceContextMode被设置成Single,客户端将在服务的生命周期内看到所有调用的次数。如果InstanceContextMode被设置成PerCall,客户端将总是看到一次调用的次数。

      注意在类中使用一个锁来同步n_calls变量。因为ConcurrencyMode被设置成Multiple,多个线程将会在实例会话范围内执行,所以这很必要。

    列表5.5 PerSession 实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    [DataContract]
       public class StockPrice
       {
           [DataMember]
           public double price;
           [DataMember]
           public int calls;
       }
     
       [ServiceContract(SessionMode= SessionMode.Required)]
       public interface IStockService
       {
           [OperationContract]
           StockPrice GetPrice(string ticker);
       }
     
       [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
       public class StockService : IStockService
       {
           object lockThis = new object();
           int n_Calls = 0;
           StockService()
           {
               Console.WriteLine("{0}:Created new instance of StockService on thread", DateTime.Now);
           }
           public StockPrice GetPrice(string ticker)
           {
               StockPrice p = new StockPrice();
     
               Console.WriteLine("{0}: GetPrice called on thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
               p.price = 94.85;
               lock (lockThis)
               {
                   p.calls = ++n_Calls;
               }
               Thread.Sleep(5000);
               return p;
           }
       }

    图片5.5 显示了两个客户端(左边)输出和服务端(右边)输出。因为两个客户端并发执行,所以左边有两个窗口。每个客户端异步调用GetPrice三次。服务端输出显示服务类有两个实例被创建-每个客户端会话一个实例。注意每个客户端只能查看它们发送请求数目,而不是服务端处理的所有请求数目。这是因为计数器,n_Calls,存储在服务会话实例中,所以每个实例有一个初始化为0的计数器。如果InstanceContextMode变成PerCall,每个客户端输出将会看到每个成功的调用计数都是1.如果InstanceContextMode改成Single,每个客户端将会看到成功调用数目从1变成6,取决于两个客户端调用。

    图片5.5 会话敏感服务输出

  • 相关阅读:
    .NET实现Excel文件的读写 未测试
    权限管理设计
    struts1中配置应用
    POJ 2139 Six Degrees of Cowvin Bacon(floyd)
    POJ 1751 Highways
    POJ 1698 Alice's Chance
    POJ 1018 Communication System
    POJ 1050 To the Max
    POJ 1002 4873279
    POJ 3084 Panic Room
  • 原文地址:https://www.cnblogs.com/Alex80/p/4281518.html
Copyright © 2011-2022 走看看