使用wsHttpBinding时,为什么InstanceContextMode.PerSession的行为与PerCall类似?

时间:2012-12-06 14:52:53

标签: ajax wcf soap wshttpbinding wcf-sessions

我使用SOAP 1.2使用AJAX客户端使用WCF服务

的Web.config:

<endpoint address="" binding="wsHttpBinding" 
contract="WcfService1.IService1" bindingConfiguration="wsHttpBin">

<wsHttpBinding>
  <binding name="wsHttpBin">
    <security mode="None"/>          
  </binding>
</wsHttpBinding>

根据我的read,我必须使用<security mode="None"/>,因为使用“wsHttpBinding”绑定公开的服务实现了WS- * Web服务规范系列的WS-Security。由于绑定使用安全性,因此请求将被拒绝,因为AJAX不支持安全上下文。

我的WCF服务行为是使用InstanceContextMode.PerSession

定义的
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
                 InstanceContextMode = InstanceContextMode.PerSession)]

但是当我使用它时,该服务表现为PerCall,并且每次调用都会启动一个新的WCF实例,而不是使用当前实例。

使用wsHttpBinding时,为什么InstanceContextMode.PerSession的行为与PerCall类似?

我该怎么办?

2 个答案:

答案 0 :(得分:4)

当使用HTTP时,会话仅在使用安全会话或可靠会话时由WCF支持。如果你不能使用任何一个,那么你必须自己实现一个会话机制。如果您同时控制客户端和服务器端,那么这样做很容易。方法如下:

创建一个类,其中包含您需要存储的所有会话数据(让我们称之为SessionData),以及上次使用会话时的额外DateTime。然后将static ConcurrentDictionary<string, SessionData>添加到您的服务类(或任何其他类)。

当客户端调用您的服务时,要求它传递一个标识会话的唯一字符串(它可以在客户端随机生成)。每当客户端调用您的服务时,在字典中查找会话字符串并检索会话数据(并根据需要更新其内容)。如果它不存在,请在字典中创建一个新条目。此外,每次访问SessionData对象时,请将“上次使用的”DateTime更新为当前时间。后台任务应定期清除一段时间内未使用过的旧会话。

就是这样 - 你已经实现了自己的会话。您现在可以使用InstanceContextMode.Single,而不必担心WCF会在每个会话中正确创建服务类的实例。

编辑:如果您使用.NET 4.5编写WCF服务并且Web应用程序仅针对现代浏览器,则可以在服务器端使用NetHttpBinding,在客户端使用WebSocket侧。 NetHttpBinding支持会话(指定SessionMode.Required时)。

答案 1 :(得分:0)

这个link给你几乎所有你需要了解的信息(一般来说)。

但要准确。 Msdn说关于WCF会话:

  

它们由调用显式启动和终止   应用

我必须说我不知道​​任何允许你存储明确打开的WCF通信通道以保持你的“会话”活着的JS代码/框架。 (您尚未提供客户端代码,因此我必须做出一些假设)。 WCF会话不是“基于cookie”。它不像您的ASP.NET Web应用程序那样在您的浏览器中“开箱即用”。

设置InstanceContextMode.PerSession会使您的WCF服务“准备就绪”,但仅仅“强制”会话是不够的。