简体   繁体   English

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

[英]Why InstanceContextMode.PerSession behave like PerCall when using wsHttpBinding?

I have WCF service consumed by AJAX client using SOAP 1.2 我有使用SOAP 1.2的AJAX客户端使用的WCF服务

Web.config: Web.config:

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

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

From what I have read , I have to use <security mode="None"/> since a service exposed with “wsHttpBinding” binding implements WS-Security of WS-* family of web service specifications. 从我所读的内容中 ,我必须使用<security mode="None"/>因为公开了“ wsHttpBinding”绑定的服务实现了WS- *系列Web服务规范的WS-Security。 As the binding uses security, the request will be rejected since AJAX doesn't support the security context. 由于绑定使用安全性,因此该请求将被拒绝,因为AJAX不支持安全性上下文。

My WCF service behavior is defined with InstanceContextMode.PerSession : 我的WCF服务行为是通过InstanceContextMode.PerSession定义的:

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

but when I consume it, the service behave as PerCall and every call starts a new WCF instance instead of using the current instance. 但是当我使用它时,该服务的行为就像PerCall一样,每个调用都会启动一个新的WCF实例,而不是使用当前实例。

Why InstanceContextMode.PerSession behave like PerCall when using wsHttpBinding? 为什么使用wsHttpBinding时InstanceContextMode.PerSession的行为类似于PerCall?

What can I do? 我能做什么?

Sessions, when used over HTTP, are only supported by WCF when using security sessions or reliable sessions. 通过HTTP使用会话时,只有使用安全会话或可靠会话的WCF才支持会话。 If you can't use either then you have to implement a session mechanism by yourself. 如果您不能使用任何一种,则必须自己实现会话机制。 If you control both the client and the server side, it would be quite easy to do it. 如果同时控制客户端和服务器端,则将非常容易。 Here's how: 这是如何做:

Create a class that holds all the session data you need stored (let's call it SessionData ), plus an additional DateTime for when the session was last used. 创建一个类,该类包含您需要存储的所有会话数据(我们将其SessionData ),以及用于最后一次使用会话的其他DateTime Then add to your service class (or any other class) a static ConcurrentDictionary<string, SessionData> . 然后将static ConcurrentDictionary<string, SessionData>添加到您的服务类(或任何其他类)中。

When a client makes a call to your service, require it to pass a unique string that identifies the session (it can be randomly generated on the client side). 当客户端调用您的服务时,要求它传递一个唯一的字符串来标识会话(可以在客户端随机生成)。 Whenever a client calls you service, look up the session string in the dictionary and retrieve the session data (and update its content as needed). 每当客户致电给您服务时,请在字典中查找会话字符串并检索会话数据(并根据需要更新其内容)。 If it doesn't exist, create a new entry in the dictionary. 如果不存在,请在字典中创建一个新条目。 Also, every time you access the SessionData object, update the 'last used' DateTime to the current time. 另外,每次访问SessionData对象时,请将“上次使用”的DateTime更新为当前时间。 A background task should periodically clear out old sessions that haven't been used in a while. 后台任务应定期清除一段时间内未使用的旧会话。

That's it - you've implemented sessions on your own. 就是这样-您已经实现了自己的会话。 You can now use InstanceContextMode.Single and not worry about WCF correctly creating instances of your service class per session. 现在,您可以使用InstanceContextMode.Single而不必担心WCF在每个会话中正确创建服务类的实例。

EDIT : If you're writing your WCF service with .NET 4.5 and you web application only targets modern browsers, you can use NetHttpBinding on the server side and WebSocket on the client side. 编辑 :如果您正在使用.NET 4.5编写WCF服务,并且您的Web应用程序仅针对现代浏览器,则可以在服务器端使用NetHttpBinding ,在客户端使用WebSocket。 NetHttpBinding supports session (when specifying SessionMode.Required ). NetHttpBinding支持会话(在指定SessionMode.Required )。

This link gives You pretty much all You need to know about this (in general of course). 链接为您提供了几乎所有您需要了解的内容(当然,通常如此)。

But to precise. 但要精确。 Msdn says about WCF session: Msdn关于WCF会话说:

They are explicitly initiated and terminated by the calling application 它们由调用应用程序显式启动和终止

I must say that I don't know about any JS code/framework that would allow You to store explicitly opened WCF communication channel to keep Your "session" alive. 我必须说,我不知道任何允许您存储显式打开的WCF通信通道以保持“会话”存活的JS代码/框架。 (You haven't provided your client code so I must make some assumptions). (您尚未提供客户代码,因此我必须做一些假设)。 WCF session is not "cookie-based". WCF会话不是“基于cookie”。 It doesn't work "out of the box" from your browser like it would for ASP.NET web application. 它无法像ASP.NET Web应用程序那样从浏览器中“立即可用”。

Setting InstanceContextMode.PerSession makes Your WCF service "session-ready" but it is not enough to "force" a session. 设置InstanceContextMode.PerSession可使WCF服务“会话就绪”,但不足以“强制”会话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM