在我正在进行的项目中,我们使用WCF
实现了多项服务。我面临的情况是某些服务需要知道会话何时结束,以便它可以适当地更新该客户端的状态。在客户端正常终止时通知服务(例如,用户关闭应用程序)很容易,但是,有些情况下应用程序可能会崩溃,或者客户端计算机可能会重新启动,在这种情况下客户端将无法通知关于其地位的服务。
最初,我在考虑在服务器端安装一个计时器,一旦客户端连接就会触发,并在1分钟之后将该客户端的状态更改为“已终止”。现在,客户端每30秒向服务发送一次状态,服务基本上会在客户端的每个请求中重新启动计时器,这意味着只要客户端处于活动状态,它就会(希望)永远不会改变客户端的状态。
即使这种方法非常可靠(不完全可靠;如果客户端需要超过1分钟才能发送其状态?),它仍然不是解决此问题的最佳方法。请注意,由于系统的原始设计,我无法实现双工服务,这可能会使事情变得更加简单。所以我的问题是:服务器有没有办法知道会话何时结束(即连接超时或客户端关闭代理)?我遇到了这个问题:WCF: How to find out when a session is ending但答案上的链接似乎已被打破。
我担心的另一件事是;我正在创建我的频道代理的方式是这样实现的:
internal static TResult ExecuteAndReturn<TProxy, TResult>(Func<TProxy, TResult> delegateToExecute)
{
string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(TProxy));
var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
TResult valueToReturn;
using (ChannelFactory<TProxy> factory = new ChannelFactory<TProxy>(binding,
new EndpointAddress(new Uri(endpointUri),
EndpointIdentity.CreateDnsIdentity(ServiceEndpoints.CertificateName))))
{
TProxy proxy = factory.CreateChannel();
valueToReturn = delegateToExecute(proxy);
}
return valueToReturn;
}
因此,在进行服务调用后,通道会立即关闭(因为它位于using
块中),从服务的角度来看,这是会话终止的指示吗?如果是这样,我应该在应用程序运行时期间只保留每个服务的一个实例,通过使用单例吗?如果问题看起来有点模糊,我很抱歉,我认为会有很多像这样的问题但却无法找到类似的东西。
答案 0 :(得分:0)
是的,关闭频道会终止会话,但如果出现某种错误,那么您将受到服务超时设置的限制,如下所示:
<binding name="tcpBinding" receiveTimeout="00:00:10" />
如果发生错误,则会引入10秒的超时。
查看Managing WCF Session Lifetime with IsInitiating and IsTerminating