保持wcf回调通道无限期打开/如果发生故障则从客户端重新连接

Jos*_*sen 15 wcf distributed tcp publish-subscribe .net-3.5

我正在尝试设置这样的东西:

  • 服务器端Windows wcf服务挂起并通过tcp侦听来自客户端Windows服务的连接.
  • 当收到连接(客户端调用服务上的CheckIn方法)时,服务通过OperationContext.Current.GetCallbackChannel <T>获取回调通道
  • 此通道与唯一键一起存储在集合中(具体来说,我将回调接口,通道和密钥存储在List <ClientConnection>中,其中每个都是属性)
  • 现在应该能够根据所述唯一密钥将调用传递给该客户端服务

这首先工作,但一段时间后停止 - 我不再能够将呼叫传递给客户端.我假设它是因为连接已被内部删除,我正在尝试使用死连接.

记住,我有以下问题:

  • 我如何告诉wcf我想无限期地(或尽可能长)保持这些tcp连接?
  • 我如何从客户端检查我与服务器的连接是否仍然有效,以便我可以丢弃它,如果我的连接被炒断,请再次检查服务器?

我可以想到狡猾的解决方案,但我希望有人会告诉我正确的方法.

Pau*_*ulF 15

从客户端建立连接时,应在tcp绑定中设置两个超时值(将传递给ClientBase <>或DuplexClientBase <>的绑定):

NetTcpBinding binding = new NetTcpBinding();
binding.ReceiveTimeout = TimeSpan.FromHours(20f);
binding.ReliableSession.InactivityTimeout = TimeSpan.FromHours(20f);
Run Code Online (Sandbox Code Playgroud)

我的示例使用20小时进行超时,您可以使用对您有意义的任何值.然后,WCF将尝试在这段时间内保持客户端和服务器的连接.默认是相对简短的(可能是5分钟?),可以解释为什么你的连接被删除.

每当客户端和服务器之间存在通信问题时(包括WCF本身丢弃通道),WCF将在客户端引发一个Faulted事件,您可以处理该事件以做任何您认为合适的事情.在我的项目中,我将我的DuplexClientBase <>派生对象转换为ICommunicationObject以获取Faulted事件并将其转发到我的类中暴露的名为OnFaulted的事件:

ICommunicationObject communicationObject = this as ICommunicationObject;
communicationObject.Faulted +=
   new EventHandler((sender, e) => { OnFaulted(sender, e); });
Run Code Online (Sandbox Code Playgroud)

在上面的代码片段中,this是我的WCF客户端类型的一个实例,在我的例子中,它是从DuplexClientBase <>派生的.您在此活动中所做的工作特定于您的申请.在我的情况下,应用程序是一个非关键的UI,所以如果有WCF错误我只是向最终用户显示一个消息框并关闭应用程序 - 如果它总是这么容易就会是一个美好的世界!