• 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 实例

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

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

    图片5.5 会话敏感服务输出


    ========

    转载自

     

  • 相关阅读:
    设计模式 23
    生活杂谈
    设计模式经典书籍
    ABP 样板开发框架系列
    关键字
    vs 2015
    优秀文章推荐
    Parallel 并行编程
    CSRF
    sql性能优化
  • 原文地址:https://www.cnblogs.com/llbofchina/p/2094050.html
Copyright © 2020-2023  润新知