If I have a session-less binding, are there any circumstances under which the client channel will fault?
In my specific case I have the following custom binding:
<customBinding>
<binding name="MyCustomBinding">
<mtomMessageEncoding/>
<httpTransport/>
</binding>
</customBinding>
On the client side I'm using the default generated proxies that derive from ClientBase<T>.
I was expecting that if the service threw an unhandled exception that was not a FaultException that it would cause the channel to be faulted and make the client proxy fault as well. However, that is not the case--the proxy still remained in the Open state and was usable afterwards. I also tried violating one of the Binding's timeouts--this also did not fault the channel and the client proxy remained in the Open state.
Is there any situation that will cause the client proxy to become faulted?
Related:
Custom WCF Binding Suppresses Fault
A ClientChannel transitions to the Faulted-State when an an unrecoverable error occurs. In this state is is not usable anymore. The recovery strategy is to create a new object. Primary reasons are
If the Open method fails for any reason, the object transitions to the faulted state.
If a session-based channel detects an error that it cannot recover from, it transitions to the faulted state. This can happen for instance if there is a protocol error (that is, it receives a protocol message at an invalid time) or if the remote endpoint aborts the session.
Taken from CommunicationState
session-based referes to a Transport Session. So any unhandled exception will fault the channel, to prevent from using the proxy again after the exception. When there is no transport-level session the client can keep using the proxy after an exception, except again, it should not.
More information about the state changes.
Related
I host a WCF Service on IIS and have the following binding in web.config:
<bindings>
<wsHttpBinding>
<binding name="transactionalBinding"
transactionFlow = "true"
sendTimeout = "00:00:01"
receiveTimeout = "00:00:01"
openTimeout = "00:00:01"
closeTimeout = "00:00:01">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
</security>
</binding>
</wsHttpBinding>
</bindings>
In my service method I sleep for 10 seconds. I do not get a timeout exception when calling my service method from a client.
Is there any meaning in defining timeouts in server side bindings?
I do not get a timeout exception when calling my service method from a client.
TL;DR: because WCF timeouts by default are one minute so naturally a server operation that only takes 10 seconds isn't going to timeout. The timeouts you have specified on the server would only affect transmission not execution of your method. (you aren't calling anything else)
You are specifying the timeouts in the server config. What you need to do is specify the timeouts in the client's config file, specifically SendTimeout. Essentially whatever end is making the call, needs to specify the operation timeout. Probably not relevant in your case but if your "server" in turn made another WCF call to another service, you would want your own timeout there too.
MSDN:
SendTimeout – used to initialize the OperationTimeout, which governs the whole process of sending a message, including receiving a reply message for a request/reply service operation. This timeout also applies when sending reply messages from a callback contract method.
Generally, WCF client and server configs should match one another and unless you are using Add Service Reference/Refresh Service Reference each time the server contracts and/or config change, the client won't know about it. By the way, avoid the latter because it duplicates your model and can lead to runtime errors if they are out of sync. Not to mention service contracts can get out of sync.
A passing thought
And this brings up one of the problems of WCF configuration via config files, they are subject to runtime errors impossible to find at compile time.
A better practice is to do away with config files completely and do programatic configuration via a common assembly that both your client and server use. Specify bindings in code along with your timeouts.
That way both server and client are always in sync with regards to WCF configuration.
With both client and server agreeing on timeouts would have addressed some issues.
Tell me more
WCF the Manual Way… the Right Way
I am using WCF with NetTcp binding and castle windsor as dependency injection at client side.
I am recieving Socket exceptions at client side sometimes, not always. Tried with different config setting but no luck. exceptions occruence are completely random.
few error messages:
An existing connection was forcibly closed by the remote host
System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Security.SecuritySessionClientSettings`1+ClientSecurityDuplexSessionChannel[System.ServiceModel.Channels.IDuplexSessionChannel], cannot be used for communication because it is in the Faulted state.
Error loading CubeDrillThroughAttributeSets cache: System.ServiceModel.ProtocolException: This channel can no longer be used to send messages as the output session was auto-closed due to a server-initiated shutdown. Either disable auto-close by setting the DispatchRuntime.AutomaticInputSessionShutdown to false, or consider modifying the shutdown protocol with the remote server.
Error loading Locations cache: System.ServiceModel.CommunicationObjectAbortedException: The communication object, System.ServiceModel.Security.SecuritySessionClientSettings`1+ClientSecurityDuplexSessionChannel[System.ServiceModel.Channels.IDuplexSessionChannel], cannot be used for communication because it has been Aborted.
WCF service is configured with PerCall instance mode.
At the client side, I am using dependency injection to inject WCF service proxy (proxy is created using channel factory).
I am not explicitly opening/closing connection with WCF service and leaving this to DI.
already tried using google. my questions are...
using DI for proxy management is good?
How the life time of proxy will be managed.
These proxies are injected in construtor when user select to load some screens in UI app. Can these proxy be timedout as per defined in client app.config file if user just open some screen and not doing anything. if yes, then what is the good way for not to timedout.
are these proxy using WCF connection pooling feature.
Thanks in advance.
I have a problem with my WCF application. I use a netTcpBinding for my application. And on the client side, I use ClientBase<> to connect to the host, and ICommunicationObject.State to check if the channel is still available.
The problem is after the "receiveTimeout", the TCP connection is cut, but in the client side, when I check the state, it still "Opened". And when I try to use it directly, there are exceptions.
To comfirm the disconnection of TCP socket, I use TCPView to monitor it. It is cut off after the timeout. But the state of channel is not updated.
Acutally, I add the diagnostic log in the config of server.
And I get an exception just after the timeout(at the same time the disconncection happens).
Here is the exception(on the server side):
System.ServiceModel.CommunicationObjectAbortedException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Net.Sockets.SocketException, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
A TCP error (995: The I/O operation has been aborted because of either a thread exit or an application request) occurred while transmitting data.
And if I try to call the service again from client, on the client side, I get this exception:
System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue.
I think it's normal for the exception on the client side. But I don't know if I need to handle the exceptions on the server side.
Someone has an idea?
Thanks every much.
The CommunicationState will stay as 'Opened' unless you explicitly Close() it or there is a fault with the Channel. Unfortunately, in your scenario until such point as you attempt to use said Channel, there is no way to determine if it is actually available apart from checking for an Exception.
I would suggest that you do not attempt to keep a Channel open past the point of it being used and explictly Close() it once you are done.
We have a wrapper that encapsulates the call, including the creation of a proxy, the service call itself and the subsequent closure of the channel and this works well.
I have a duplex WCF service with sessions enabled, and I'm trying avoid fault state exceptions on the client.
I found several discussions arround this topic, but all I have found suggest to recreate the client proxy or channel. Non is focus in duplex services with session enabled.
My problem with that approach is that there is one session per client in the server, and each client has only one instance of the service proxy (singleton service proxy). Because it is duplex, in the client side several objects are listening to events on that service instance (messages sent from the server to the client).
If the service is in faulted state, it can not be used any more. If I discard that instance and create a new one, I'm finding it hard to hook up all the event handlers again to this new instance.
Should I wrap the service and every time an object hooks up for an event, store the handler in a list (so that I can re hook it when service is recreated)? Seems to be lost of code, easy to leak memory...
Is there a way to just restart the client proxy / channel, without discarding all the proxy instance? (I'm using the VS generated proxy)
Any ideas?
Thanks,
MAB
You cannot restart the proxy. The only recovery from faulted state is aborting current instance and recreating the new one. On the client side you must correctly unregister everything dependent on your proxy instance, create new instance and register everything again. This whole operation must happen once you get the exception about channel in faulted state (= when you try to call the service). After recreation you must call the service again.
On the service side the instance is either already dead (that caused the faulted state of the channel) or it will die after session timeout. You must also handle faulted exception when you try to callback on the faulted channel by removing the channel from your known clients and unregistering anything dependent on that channel.
I'm trying to get a better understanding of what's going on when I use a WCF proxy. I'm having trouble understanding what happens when I close (or don't close) a proxy.
What's going on when I call Close() or Abort() on a WCF proxy? What's the difference?
How does it differ between types of bindings (like, a sessionless BasicHttpBinding vs. something sessionful)?
Why can Close() throw in certain situations and why can it be a blocking operation?
Closing WCF client
A client has an inherited responsibility of gracefully closing the connection. It is always recommended to close a proxy client. If the binding between a client and a service is transport-layer sessionful, then closing a proxy is essential to tear down the connection between both parties. Service has a payload threshold defined for concurrent connections. If the number of concurrent connections goes above this threshold linearly then the overall service performance decreases exponentially. This is why it is crucial to dispose of the connection as soon as possible. Closing the proxy also notifies the service instance that it is no longer in use and may be collected by GC (subject to service instance management). If the client does not close a connection, it is still automatically torn down by WCF timeouts (found in the configuration files).
Aborting WCF client
In the situation where there is a fault in the service-client interaction, the objects on both ends are potentially totally broken. Thus using a proxy after the exception is not advised. Given the WCF binding use transport sessions, the client after a fault would not even be able to close it (if there was no transport layer session then the client could use or close the proxy, but this is not recommended as the configuration of sessions could change). So after a fault has happened the only safe operation is to abort a proxy.
Close is a synchronous operation, it can throw if the transport session has been damaged by a fault and it is a blocking operation until a confirmatory response from service is received (true for some bindings).