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

时间:2022-10-07 15:58:20

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. As the binding uses security, the request will be rejected since AJAX doesn't support the security context.

根据我的阅读,我必须使用 ,因为使用“wsHttpBinding”绑定公开的服务实现了WS- * Web服务规范系列的WS-Security。由于绑定使用安全性,因此请求将被拒绝,因为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?

我能做什么?

2 个解决方案

#1


3  

Sessions, when used over HTTP, are only supported by WCF when using security sessions or reliable sessions. 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:

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

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. Then add to your service class (or any other class) a static ConcurrentDictionary<string, SessionData>.

创建一个包含您需要存储的所有会话数据的类(让我们称之为SessionData),以及上次使用会话时的额外DateTime。然后将静态ConcurrentDictionary 添加到服务类(或任何其他类)。 ,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. A background task should periodically clear out old sessions that haven't been used in a while.

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

That's it - you've implemented sessions on your own. You can now useInstanceContextMode.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. NetHttpBinding supports session (when specifying SessionMode.Required).

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

#2


0  

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. (You haven't provided your client code so I must make some assumptions). WCF session is not "cookie-based". It doesn't work "out of the box" from your browser like it would for ASP.NET web application.

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

Setting InstanceContextMode.PerSession makes Your WCF service "session-ready" but it is not enough to "force" a session.

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

#1


3  

Sessions, when used over HTTP, are only supported by WCF when using security sessions or reliable sessions. 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:

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

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. Then add to your service class (or any other class) a static ConcurrentDictionary<string, SessionData>.

创建一个包含您需要存储的所有会话数据的类(让我们称之为SessionData),以及上次使用会话时的额外DateTime。然后将静态ConcurrentDictionary 添加到服务类(或任何其他类)。 ,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. A background task should periodically clear out old sessions that haven't been used in a while.

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

That's it - you've implemented sessions on your own. You can now useInstanceContextMode.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. NetHttpBinding supports session (when specifying SessionMode.Required).

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

#2


0  

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. (You haven't provided your client code so I must make some assumptions). WCF session is not "cookie-based". It doesn't work "out of the box" from your browser like it would for ASP.NET web application.

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

Setting InstanceContextMode.PerSession makes Your WCF service "session-ready" but it is not enough to "force" a session.

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