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.
Related
On this previous question: Tell when wcf client lost connection One of the commenters states:
Your service should not care whether a network cable was disconnected.
One feature of TCP is that unless someone is actively sending data, it
can tolerate momentary interruptions in network connectivity.
This is even more true in WCF, where there are layers of extra
framework to help protect you against network unreliability.
I'm having an issue where this is not working correctly. I have WCF client that makes a connection to the server using a DuplexChannelFactory. The connection stays open for 3 minutes. I disconnect the client from the internet and reconnect. The client regains internet connection, however any calls made from the server to that client fail. Once the client reconnects it begins working again.
When I pull the plug on the internet, the client throws several exceptions but the channel is still listed as being in an open state. Once the connection is regained and I made a request from the server to the client, I get errors such as: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.
Obviously if the request comes in when the client is offline it won't work, but I'm trying to get it so this channel will recover once the internet comes back without having to set up a new connection.
Should this be working as-is, based on the comment I listed above? Or is there something I need to change to make that actually work?
The issue here is that the channel you're trying to use is in a faulted state, and cannot be used any longer (as the error message indicates).
Your client needs to trap (catch) that exception, and then abort the current channel and create a new one. WCF will not do that for you automatically, you have to code for it yourself.
You could also check the CommunicationState of the channel to see if it is faulted, and recover that way.
A final option would be to use the OnFaulted event handler, and when the channel is faulted, abort the channel and create a new one.
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.
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.
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).
I'm making a call to a WCF service but I get a CommunicationException on the client while receiving the response from the service.
System.ServiceModel.CommunicationException: An error occurred while receiving the HTTP response to http://localhost:8080/Service. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
The client that makes the call is a WCF proxy client.
The service method executes without
any exceptions.
The WCF call works fine in those cases where it does not
take a long time for the serivce
method to finish.
The WCF call fails with the above exception message when the service method is taking long time to finish.
The sendTimeout property of the client's binding has been increased to 30 minutes to accommodate the time it can take for the service method to finish.
Try to set the receiveTimeout equal or greater than the time it takes for the service method to complete. The default value for the receiveTimeout property is 10 minutes. So if the service method takes longer time to complete the connection will be closed (if no other activity takes place before the receiveTimeoutoccurs). The receiveTimeout property is described here.
A very long operation like this should most likely be called asynchronously - in other words, the client asks the server to prepare the data, then gets on with something else while the server does the work. When the server's finished it calls the client back.
Asynchronous WCF operations are discussed here.