Asp.Net教程,WinForm教程,Asp.Net MVC,vs2008教程,vs2010教程,Silverlight技术,源码下载,Asp.Net视频教程
全站热门标签
vs2010 Silverlight 存储过程 水晶报表 ADO.NET JavaScript LINQ AjaxPro DataGridView 面向对象 Extjs GridView XML DevExpress HTML教程 Oracle jQuery 分页 GDI+ Visual C++2010 MySQL Office2010 WPF MVC Dojo WCF4.0 VB.NET Sql2005 textbox cookie WCF WinForm Discuz!NT SQL经典语句 T-SQL checkbox ASPxGridView F# asp.net SQL VS2008新特性 DropDownList Access TreeView Ajax VS2008 页面执行时间 Flex 字符串 回调 VB2005 DataSet C#时间 ASP.NET性能优化 用户在线检测 动画
Framework C#技术 VB.NET VC.NET WCFWPF
当前位置: 主页 > WinForm教程 > WPF >

WCF学习序列(六):会话状态

时间:2009-12-24 00:11来源:未知 作者:admin 点击:

WCF 会话状态和两个端点(EndPoint)之间的一系列消息交换相关联,它实际上是 "实例上下文(Instance Context)”,控制着服务对象实例的创建方式和生存期。和 ASP.NET Session 有很大不同。

  WCF Session 特点:

  由调用程序(Calling Application)发起初始化和终止操作。

  由具体的 Binding 类型实现,因此它们之间的细节可能有所不同。

  不提供 ASP.NET Session 那样的数据容器。

  启动 Session 的方法包括:

  调用 Channel 的 Open 方法。我们可以使用 ChannelFactory 来创建 Channel。

  调用客户端代理对象的 Open 方法(ClientBase.Open)。

  调用任何允许初始化会话服务方法(缺省情况下所有的服务方法都自动初始化Session,也就是 IsInitiating=true)。

  结束 Session 的方法包括:

  调用 Channel 的 Close 方法。

  调用客户端代理对象的 Close 方法(ClientBase.Close)。

  调用任何包含 "IsTerminating=true" 声明的服务方法(缺省情况下所有的服务方法 IsTerminating=false,需要我们显示声明)。

  要使用 WCF Session,我们一般按如下步骤进行。

  1. 开启服务契约的 Session。

  可以选择的模式包括:Required、Allowed、NotAllowed。Required 表示必须使用 Session,如果 Binding 不支持,则会抛出异常;Allowed 表示如果 Binding 支持 Session 则开启会话;NotAllowed 表示停用 Session。多数 Binding 缺省就会开始 Session,而 BaseHttpBinding 不支持 Session。

[ServiceContract(SessionMode=SessionMode.Required)]
public interface ICalculate
{
  [OperationContract]
  int Add(int a, int b);
}

输出:

2. 使用 ServiceBehaviorAttribute 和 InstanceContextMode 在服务契约的实现类型上指定服务对象的 "实例上下文模式"。

  InstanceContextMode 可选择的方式包括:PerSession、PerCall、Single。PerSession 表示为每个连接(每个客户端代理对象) 创建一个会话(服务对象);PerCall 则为每次调用(Operate)创建一个会话(服务对象);Single 则表示所有的客户端共享一个会话(服务对象)。

[ServiceContract(SessionMode=SessionMode.Required)]
public interface ICalculate
{
  [OperationContract]
  int Add(int a, int b);
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class CalculateService : ICalculate
{
  public CalculateService()
  {
    Console.WriteLine("Constructor {0}...", this.GetHashCode());
  }
  public int Add(int a, int b)
  {
    Console.WriteLine(OperationContext.Current.SessionId);
    return a + b;
  }
}
public class WcfTest
{
  public static void Test()
  {
    AppDomain.CreateDomain("Server").DoCallBack(delegate
    {
      ServiceHost host = new ServiceHost(typeof(CalculateService));
      host.AddServiceEndpoint(typeof(ICalculate), new WSHttpBinding(), 
        "http://localhost:8080/calc");
      host.Open();
    });
    ChannelFactory<ICalculate> factory = new ChannelFactory<ICalculate>(new WSHttpBinding(), 
      "http://localhost:8080/calc");
    ICalculate o = factory.CreateChannel();
    Console.WriteLine(o.Add(1, 2));
    Console.WriteLine(o.Add(1, 2));
    Console.WriteLine(o.Add(1, 2));
  }
}

Constructor 30136159...
urn:uuid:9fc72020-3ba3-442b-be1c-f2faf06a46d3
3
urn:uuid:9fc72020-3ba3-442b-be1c-f2faf06a46d3
3
urn:uuid:9fc72020-3ba3-442b-be1c-f2faf06a46d3
3

 3. 如果有必要,可以使用 OperationContractAttribute 的 IsInitiating 和 IsTerminating 属性来控制每次调用对 Session 的操控。

  IsInitiating 表示该方法是否可以初始化 Session,IsTerminating 表示该方法是否可以终止 Session。默认设置 IsInitiating=true,IsTerminating=false。

  我们将上面例子改一下。

[ServiceContract(SessionMode=SessionMode.Required)]
public interface ICalculate
{
  [OperationContract(IsTerminating=true)]
  int Add(int a, int b);
}

  在客户端第二次调用 Add 方法时会抛出异常。

  未处理 System.InvalidOperationException

  Message="This channel cannot send any more messages because IsTerminating operation 'Add' has already been called."

  Source="mscorlib"

  StackTrace:

  Server stack trace:

  在 System.ServiceModel.Channels.ServiceChannel.PrepareCall(ProxyOperationRuntime operation, Boolean oneway, ProxyRpc& rpc)

  ......

  我们继续修改上面例子。

[ServiceContract(SessionMode=SessionMode.Required)]
public interface ICalculate
{
  [OperationContract(IsInitiating = false)]
  int Add(int a, int b);
}

  第一次调用 Add 方法,触发异常。

未处理 System.InvalidOperationException

  Message="ContractDescription 'ICalculate' has zero IsInitiating=true operations; a contract must have at least one IsInitiating=true operation."

  Source="System.ServiceModel"

  StackTrace:

  在 System.ServiceModel.Description.ContractDescription.EnsureInvariants()

  ......

  我们可以增加一个额外的方法来初始化会话,如下。OK,这次没问题了。

[ServiceContract(SessionMode=SessionMode.Required)]
public interface ICalculate
{
  [OperationContract(IsInitiating=true)]
  void Initiate();
  [OperationContract(IsInitiating=false)]
  int Add(int a, int b);
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class CalculateService : ICalculate
{
  public CalculateService()
  {
    Console.WriteLine("Constructor {0}...", this.GetHashCode());
  }
  public void Initiate()
  { 
  }
  public int Add(int a, int b)
  {
    Console.WriteLine(OperationContext.Current.SessionId);
    return a + b;
  }
}
public class WcfTest
{
  public static void Test()
  {
    AppDomain.CreateDomain("Server").DoCallBack(delegate
    {
      ServiceHost host = new ServiceHost(typeof(CalculateService));
      host.AddServiceEndpoint(typeof(ICalculate), new WSHttpBinding(), 
        "http://localhost:8080/calc");
      host.Open();
    });
    ChannelFactory<ICalculate> factory = new ChannelFactory<ICalculate>(new WSHttpBinding(), 
      "http://localhost:8080/calc");
    ICalculate o = factory.CreateChannel();
    o.Initiate();
    Console.WriteLine(o.Add(1, 2));
  }
}

(责任编辑:admin)
Tags:WCF
责任编辑:admin
返回顶部
------分隔线----------------------------
推荐内容
骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价 骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价