0

在我正在进行的项目中,我们有几个使用WCF. 我面临的情况是某些服务需要知道会话何时结束,以便它可以适当地更新该客户端的状态。当客户端正常终止时通知服务(例如用户关闭应用程序)很容易,但是,在某些情况下应用程序可能会崩溃,或者客户端计算机可能会重新启动,在这种情况下客户端将无法通知服务关于它的状态。

最初,我正在考虑在服务器端设置一个计时器,它会在客户端连接后触发,并在例如 1 分钟后将该客户端的状态更改为“已终止”。现在客户端每 30 秒将其状态发送给服务,并且服务基本上会在客户端的每个请求上重新启动其计时器,这意味着它(希望)永远不会改变客户端的状态,只要客户端还活着。

尽管这种方法非常可靠(不完全可靠;如果客户端发送其状态的时间超过 1 分钟怎么办?)它仍然不是解决此问题的最佳方法。请注意,由于系统的原始设计,我无法实现双工服务,这可能会使事情变得更简单。所以我的问题是:有没有办法让服务知道会话何时结束(即连接超时或客户端关闭代理)?我遇到了这个问题:WCF:如何找出会话何时结束,但答案上的链接似乎已损坏。

我担心的另一件事是;他们目前正在创建我的频道代理的方式是这样实现的:

  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块中),从服务的角度来看,这是否表明会话已终止?如果是这样,我是否应该在应用程序运行时只保留每个服务的一个实例,也许可以使用单例?如果问题看起来有点模糊,我深表歉意,我认为会有很多这样的问题,但无法找到类似的问题。

4

1 回答 1

0

是的,关闭通道会终止会话,但是如果出现某种错误,那么您将受到服务的超时设置的影响,如下所示:

<binding name="tcpBinding" receiveTimeout="00:00:10" />

如果发生错误,这会引入十秒超时。

查看使用 IsInitiating 和 IsTerminating 管理 WCF 会话生命周期

于 2013-07-18T17:45:35.167 回答