8

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

网络配置:

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

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

根据我的阅读,我必须使用,<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?

我能做些什么?

4

2 回答 2

4

通过 HTTP 使用的会话仅在使用安全会话或可靠会话时受 WCF 支持。如果你不能使用,那么你必须自己实现一个会话机制。如果您同时控制客户端和服务器端,那将很容易做到。就是这样:

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

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

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

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

于 2012-12-09T16:29:35.413 回答
0

链接为您提供了您需要了解的几乎所有信息(当然一般而言)。

但要准确。Msdn 谈到 WCF 会话:

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

我必须说,我不知道任何 JS 代码/框架可以让您显式存储打开的 WCF 通信通道以保持您的“会话”处于活动状态。(您还没有提供您的客户端代码,所以我必须做出一些假设)。WCF 会话不是“基于 cookie”的。它不像 ASP.NET Web 应用程序那样在浏览器中“开箱即用”。

设置InstanceContextMode.PerSession使您的 WCF 服务“会话就绪”,但不足以“强制”会话。

于 2012-12-09T16:52:27.987 回答