简体   繁体   English

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

[英]keeping a wcf callback channel open indefinitely / reconnecting from client if it faults

i'm currently trying to set up something like this: 我正在尝试设置这样的东西:

  • a server side windows wcf service hangs out and listens via tcp for connections from a client side windows service. 服务器端Windows wcf服务挂起并通过tcp侦听来自客户端Windows服务的连接。
  • when a connection is received (the client calls the CheckIn method on the service) the service obtains a callback channel via OperationContext.Current.GetCallbackChannel<T> 当收到连接(客户端调用服务上的CheckIn方法)时,服务通过OperationContext.Current.GetCallbackChannel <T>获取回调通道
  • this channel is stored in a collection along with a unique key (specifically, i store the callback interface, the channel, and the key in a List<ClientConnection> where each of those is a property) 此通道与唯一键一起存储在集合中(具体来说,我将回调接口,通道和密钥存储在List <ClientConnection>中,其中每个都是属性)
  • calls should now be able to be passed to that client service based on said unique key 现在应该能够根据所述唯一密钥将调用传递给该客户端服务

this works at first, but after a while stops -- i'm no longer able to pass calls to the client. 这首先工作,但一段时间后停止 - 我不再能够将呼叫传递给客户端。 i'm assuming it's because the connection has been dropped internally and i'm trying to work with a dead connection. 我假设它是因为连接已被内部删除,我正在尝试使用死连接。

that in mind, i've got the following questions: 记住,我有以下问题:

  • how do i tell wcf i want to keep those tcp connections indefinitely (or for as long as possible)? 我如何告诉wcf我想无限期地(或尽可能长)保持这些tcp连接?
  • how do i check, from the client side, whether or not my connection to the server is still valid so i can drop it and check in with the server again if my connection is fried? 我如何从客户端检查我与服务器的连接是否仍然有效,以便我可以丢弃它,如果我的连接被炒断,请再次检查服务器?

i can think of gimpy solutions, but I'm hoping someone here will tell me the RIGHT way. 我可以想到狡猾的解决方案,但我希望有人会告诉我正确的方法。

When you establish the connection from the client, you should set two timeout values in your tcp binding (the binding that you will pass to ClientBase<> or DuplexClientBase<>): 从客户端建立连接时,应在tcp绑定中设置两个超时值(将传递给ClientBase <>或DuplexClientBase <>的绑定):

NetTcpBinding binding = new NetTcpBinding();
binding.ReceiveTimeout = TimeSpan.FromHours(20f);
binding.ReliableSession.InactivityTimeout = TimeSpan.FromHours(20f);

My sample uses 20 hours for timeout, you can use whatever value makes sense for you. 我的示例使用20小时进行超时,您可以使用对您有意义的任何值。 Then WCF will attempt to keep your client and server connected for this period of time. 然后,WCF将尝试在这段时间内保持客户端和服务器的连接。 The default is relatively brief (perhaps 5 minutes?) and could explain why your connection is dropped. 默认是相对简短的(可能是5分钟?),可以解释为什么你的连接被删除。

Whenever there is a communication problem between the client and server (including WCF itself dropping the channel), WCF will raise a Faulted event in the client, which you can handle to do whatever you feel appropriate. 每当客户端和服务器之间存在通信问题时(包括WCF本身丢弃通道),WCF将在客户端引发一个Faulted事件,您可以处理该事件以做任何您认为合适的事情。 In my project, I cast my DuplexClientBase<> derived object to ICommunicationObject to get a hold of the Faulted event and forward it to an event called OnFaulted exposed in my class: 在我的项目中,我将我的DuplexClientBase <>派生对象转换为ICommunicationObject以获取Faulted事件并将其转发到我的类中暴露的名为OnFaulted的事件:

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

In the above code snippet, this is an instance of my WCF client type, which in my case is derived from DuplexClientBase<>. 在上面的代码片段中, this是我的WCF客户端类型的一个实例,在我的例子中,它是从DuplexClientBase <>派生的。 What you do in this event is specific to your application. 您在此活动中所做的工作特定于您的申请。 In my case, the application is a non-critical UI, so if there is a WCF fault I simply display a message box to the end-user and shut down the app - it'd be a nice world if it were always this easy! 在我的情况下,应用程序是一个非关键的UI,所以如果有WCF错误我只是向最终用户显示一个消息框并关闭应用程序 - 如果它总是这么容易就会是一个美好的世界!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM