I like using WCF callbacks when I can because to me it is better than the client having to poll the server and its more real time than polling. The question I have is when I subscribe to a WCF service event is there any kind of heart beat that keeps the connection alive between the client and the server. I starting to think that there is not because when the server goes away the subscription is lost and the client does not throw an exception (could be the exception is be swallowed by the WCF runtime). Same is true for the server, when the client goes away and the server attempts to invoke the callback and exception is throw. Any thoughts?
Thanks
There is a good short description of the Duplex contract (WCF callbacks) in this link. The duplex contract is basically two one-way channels and there is no implied message correlation. You are right, there are no "heartbeat" messages are involved, only the normal wsHTTP handshaking traffic occurs when making a duplex call.
I fired up the HTTP traffic sniffer called Fiddler2 (an unsupported Microsoft tool) to verify the session traffic. Didn't see any under-the-hood HTTP "heartbeat" communication occurring during and after the service calls. I left the client running for a good while. Good question, it got me digging a bit.
I went ahead and created a recurring heartbeat to the subscribed clients (basically a call to a function they're hosting).
I've run this for hours and it works, this helps ensure the connection.
Related
I'm developing a client/server app in which the client calls the WCF service every few seconds. I'm not using IIS - the service runs as a console app (with the intention of installing it as a Windows service on production systems).
I started off using basicHttpBinding, and if I stop the service (to simulate a comms/server failure) the client simply ignores the fact that it can't connect to the service, by handling the EndpointNotFoundException that gets thrown. After restarting the service, the client is able to start calling it again and everything is good.
I've now switched to using netTcpBinding, and this time when I stop the service it takes a little while for its console window to close (presumably due to the way TCP manages the connection, which eventually times out). At this point the client gets a CommunicationException ("the socket connection was aborted"). When I restart the service, the client isn't able to "resume" like it did with basicHttpBinding. Each time it tries to call the service it throws a CommunicationObjectFaultedException ("The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.").
How would I go about building in some kind of resume/recovery behaviour, similar to what I saw with basicHttpBinding?
You cannot reuse the channel as it has faulted. You should cast your client to an ICommunicationObject and call Abort() to clean up.
After that you simply start afresh by creating a new client channel. You may want to do this on a timer if your server is down for a period of time.
I don't think I was clear. What I meant was How to set a callback("server to client") in a different connection from a "client to server" connection using WCF ?
I always saw callbacks examples using just one DuplexChannelFactory. This implies using only one TCP connection to make client to server calls and receive server to client callbacks.
This question came to me after I read this this topic:
Seeking WCF Duplex "TwoWay" Subscribe+Callback Example
I the top answer, Ian Ringrose said:
Some rules I found to help avoid deadlocks. (Look at my WCF questions to see the pain I had!)
The sever must never call out to a client on the same connection as a call from the same client is in process on.
And/or
The client must never call back to the server on the same connection as is used for the “callbacks” while processing a call-back.
And I was wondering how to implement it using WCF.
This CodeProject on Robust Interapplication Communications using Double-Simplex WCF answers exactly your question:
What I decided to do was run two separate WCF connections (double simplex). Each application would run a WCF Host for incoming messages and each application would run a WCF Client for outgoing messages. This is a pretty robust solution and will not be broken by stopping and starting the applications. The WCF Client simply re-establishes the connection if needed.
The way it is solved meets the requirements you have extracted from the Ian Ringrose answer.
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 have a server that is calling back to the client through a callback channel.
The callback contract operations are all marked as IsOneWay. The binding is netTcp.
I sometimes have the scenario where the server is generating more messages than the client can handle (I can simulate this by putting a sleep into the client method).
Eventually I get a "CommunicationException: The socket connection was aborted"
Unfortunately I have no idea what is going on under the hood.
Is the operation queued on the send
or receive side, or both?
Can I monitor these queues?
What causes the timeout?
Does WCF have threads that constantly write/read to the socket?
Does WCF on the receive side eventually stop reading from the socket hence the timeout?
To get more info on whats going on , try to turn on WCF tracing , and using the trace viewer to look at the output. here`s how to turn on tracing, and use the MS trace view utility SvcTraceViewer.exe
in a more direct answer to the question - WCF has a default incomming queue of 10 concurrent sessions, so i'm geussing that this is what you are experiencing when the server stresses the client. it`s possible to configure a larger value though, using the maxConcurrentSessions behaviur parameter.
I have a lot of client programs and one service.
This Client programs communicate with the server with http channel with WCF.
The clients have dynamic IP.
They are online 24h/day.
I need the following:
The server should notify all the clients in 3 min interval. If the client is new (started in the moment), is should notify it immediately.
But because the clients have dynamic IP and they are working 24h/day and sometimes the connection is unstable, is it good idea to use wcf duplex?
What happens when the connection goes down? Will it automatically recover?
Is is good idea to use remote MSMQ for this type of notification ?
Regards,
WCF duplex is very resource hungry and per rule of thumb you should not use more than 10. There is a lot of overhead involved with duplex channels. Also there is not auto-recover.
If you know the interval of 3 minutes and you want the client to get information when it starts why not let the client poll the information from the server?
When the connection goes down the callback will throw an exception and the channel will close.
I am not sure MSMQ will work for you unless each client will create an MSMQ queue for you and you push messages to each one of them. Again with an unreliable connection it will not help. I don't think you can "push" the data if you loose the connection to a client, client goes off-line or changes an IP without notifying your system.