我有一个WCF服务,实例上下文模式设置为PerCall,并使用wsHttpBinding。编码不良的客户端能够在不正确释放会话的情况下使用会话(即客户端不会在客户端代理上调用Close())。通过查看“最大并发会话百分比”性能计数器,我可以看到每个连接都会耗尽会话,并且不会释放它。在正常,表现良好的情况下,会话只会在返回调用结果时使用一段时间。
我一直试图找到一种方法让这些糟糕的会话超时并消失,但一直没有成功。由于它不是可靠的会话,因此RecieveTimeout和InactivityTimeout设置似乎没有任何效果。这是我当前配置的一部分,其中设置了多个超时,但似乎不起作用:
<behaviors>
<serviceBehaviors>
<behavior name="UpdaterBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider"/>
<serviceCertificate findValue="xxxxxx" x509FindType="FindBySubjectName"/>
</serviceCredentials>
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="SqlRoleProvider"/>
<serviceThrottling maxConcurrentCalls="10" maxConcurrentSessions="10" maxConcurrentInstances="10" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="UpdaterBinding" messageEncoding="Mtom" maxReceivedMessageSize="100000000" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:01:00" sendTimeout="00:01:00">
<reliableSession ordered="true" inactivityTimeout="00:01:00"
enabled="false" />
<readerQuotas maxArrayLength="100000000"/>
<security>
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
我可以将serviceThrottling数字设置得更高,但这只会暂时隐藏问题,最终坏客户端会使用所有会话。我希望服务器释放任何已经存在超过几分钟的会话,因为这个服务上没有任何理由需要这么长时间。
有什么建议吗?
答案 0 :(得分:1)
好吧,我可能完全偏离基地,但根据我对你的问题的理解,这是一个可能的解决方案:
显然,您可以获得活动会话列表,但无法从服务端终止会话:
http://social.msdn.microsoft.com/Forums/en/wcf/thread/a6a72bd7-bd06-43e3-8abb-d6c10432a07b
我能想到的一件事是,如果您在IIS中托管WCF服务,您可以创建一个在服务器上运行并查看活动会话的Windows服务。也许你可以弄清楚会话建立何时对服务器无法管理并强制它重启IIS应用程序池?
答案 1 :(得分:1)
孤立会话的一个选项是将wsHttpBinding配置为不使用依赖于会话的任何功能(例如可靠消息传递,这是现在配置服务的方式)。
如果您的业务需求需要可靠的消息传递,那么请转到netMsmqBinding以获得有保证的消息传递,但代价是围绕单向消息传递模式进行设计。 DeviantSeev是正确的,你不能控制从服务终止会话,但他推荐的解决方案非常激烈。如果您拥有像电子商务网站这样的高容量环境,那是不可行的,因为回收应用池会导致停机。