WCF会话状态功能特点解析

开发 开发工具
WCF会话状态主要特点比较突出,我们将会在这篇文章中为大家详细介绍一下相关的应用技巧,以及他的各种启动方法等等。

WCF是一个.NET Framework 3.5的重要组成部件,可以帮助我们成功创建出一个安全性强的开发解决方案。我们在这里会为大家介绍一下WCF会话状态的相关概念。WCF会话状态和两个端点(EndPoint)之间的一系列消息交换相关联,它实际上是 "实例上下文(Instance Context)”,控制着服务对象实例的创建方式和生存期。和 ASP.NET Session 有很大不同。#t#

WCF会话状态特点:

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

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

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

启动WCF会话状态的方法包括:

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

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

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

结束WCF会话状态的方法包括:

调用 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。

 

 

  1. < ServiceContract(SessionModeSessionMode:=SessionMode.Required)> _  
  2. Public Interface IService1  
  3. < OperationContract(isinitiating:=False)> _  
  4. Function GetData(ByVal value As Integer) As String  
  5. End Interface 

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

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

 

 

  1. < ServiceBehavior(InstanceContextModeInstanceContextMode:
    =InstanceContextMode.PerSession)> _  
  2. Public Class Service1  
  3. Implements IService1  
  4. Public Function GetData(ByVal value As Integer) As String 
    Implements IService1.GetData  
  5. Console.WriteLine(OperationContext.Current.SessionId)  
  6. Return String.Format("You entered: {0}", value)  
  7. End Function  
  8. End Class 

 

客户端调用:

 

 

  1. Sub Main()  
  2. Dim url As String = "http://localhost:8731/
    Design_Time_Addresses/WcfServiceLibrary1/Service1/mex"
     
  3. Dim host As New System.ServiceModel.ServiceHost(GetType
    (WcfServiceLibrary1.Service1))  
  4. host.AddServiceEndpoint(GetType(WcfServiceLibrary1.IService1),
     New System.ServiceModel.WSHttpBinding, url)  
  5. host.Open()  
  6. Console.WriteLine(host.State.ToString)  
  7. Dim f As New System.ServiceModel.ChannelFactory
    (Of WcfServiceLibrary1.IService1)(New System.ServiceModel
    .WSHttpBinding, url)  
  8. Dim s As WcfServiceLibrary1.IService1 = f.CreateChannel  
  9. Console.WriteLine(s.GetData(1))  
  10. Console.WriteLine(s.GetData(1))  
  11. Console.WriteLine(s.GetData(1))  
  12. Console.ReadKey()  
  13. End Sub 

 

 

输出:

 

urn:uuid:e801a8b5-8419-4ec4-bfc7-a850f408a42a

urn:uuid:e801a8b5-8419-4ec4-bfc7-a850f408a42a

urn:uuid:e801a8b5-8419-4ec4-bfc7-a850f408a42a

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

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

我们将上面的例子改一下:

 

 

  1. < ServiceContract(SessionModeSessionMode:=SessionMode.Required)> _  
  2. Public Interface IService1  
  3. < OperationContract(isinitiating:=False)> _  
  4. Function GetData(ByVal value As Integer) As String  
  5. End Interface 

 

 

 

 

 

客户第一次调用时会出现异常

ContractDescription“IService1”没有 IsInitiating=true 操作;协定必须至少有一个 IsInitiating=true 操作。

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

  1. < ServiceContract(SessionModeSessionMode:=SessionMode.Required)> _  
  2. Public Interface IService1  
  3. < OperationContract(isinitiating:=False)> _  
  4. Function GetData(ByVal value As Integer) As String  
  5. < OperationContract(isinitiating:=True)> _  
  6. Sub Init()  
  7. End Interface  
  8. < ServiceBehavior(InstanceContextModeInstanceContextMode
    :
    =InstanceContextMode.PerSession)> _  
  9. Public Class Service1  
  10. Implements IService1  
  11. Public Function GetData(ByVal value As Integer) 
    As String Implements IService1.GetData  
  12. Console.WriteLine(OperationContext.Current.SessionId)  
  13. Debug.WriteLine(OperationContext.Current.SessionId)  
  14. Return String.Format("You entered: {0}", value)  
  15. End Function  
  16. Public Sub Init() Implements IService1.Init  
  17. End Sub  
  18. End Class 

客户端

 

 

  1. Sub Main()  
  2. Dim url As String = "http://localhost:8731/Design_Time_Addresses
    /WcfServiceLibrary1/Service1/mex"
     
  3. Dim host As New System.ServiceModel.ServiceHost(GetType
    (WcfServiceLibrary1.Service1))  
  4. host.AddServiceEndpoint(GetType(WcfServiceLibrary1.IService1),
     New System.ServiceModel.WSHttpBinding, url)  
  5. host.Open()  
  6. Console.WriteLine(host.State.ToString)  
  7. Dim f As New System.ServiceModel.ChannelFactory
    (Of WcfServiceLibrary1.IService1)(New System.ServiceModel.
    WSHttpBinding, url)  
  8. Dim s As WcfServiceLibrary1.IService1 = f.CreateChannel  
  9. s.Init() '初始化  
  10. Console.WriteLine(s.GetData(1))  
  11. Console.WriteLine(s.GetData(1))  
  12. Console.WriteLine(s.GetData(1))  
  13. Console.ReadKey()  
  14. End Sub 

 

 

这个示例就到这里了,对于原文有一个地方:

我们将上面例子改一下。

  1. [ServiceContract(SessionModeSessionMode=SessionMode.Required)]  
  2. public interface ICalculate  
  3. {  
  4. [OperationContract(IsTerminating=true)]  
  5. 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)

我在测试的过程,没有发现这个问题!我用的是vs2008+sp1

以上就是对WCF会话状态的相关介绍。

责任编辑:曹凯 来源: 博客园
相关推荐

2010-02-23 15:58:57

WCF Session

2010-08-03 12:53:51

FlexBuilder

2009-12-21 17:40:25

WCF会话

2010-02-23 09:51:32

WCF MTOM

2009-12-29 16:36:47

Silverlight

2009-12-31 16:50:02

Silverlight

2010-08-09 10:03:43

FlexBuilder

2009-09-04 18:00:54

C# Main方法

2011-11-18 15:01:32

笔记本评测

2015-05-11 13:20:18

云智慧透视宝

2010-02-22 15:00:02

WCF信道工厂

2009-11-05 16:12:09

WCF会话服务

2010-02-22 13:35:03

WCF异常处理

2010-02-23 10:15:22

WCF运行机制

2010-02-23 09:34:15

WCF重载

2010-02-25 14:26:48

WCF特点

2011-06-03 12:41:36

2010-09-07 15:56:37

PPPoE会话

2009-12-10 13:43:08

使用PHPExcel

2010-03-02 17:43:31

WCF框架处理流程
点赞
收藏

51CTO技术栈公众号