Can you please tell me a way to check if the client is alive on the host?
I am having problems when the client application shuts down or crashes, it does not tell the host that it is disconnecting and the client is still present in the client list on the host.
Then, any other iteraction with the host, hangs and timesout.
Look at reliable sessions in WCF. In the simplest case you can just add <reliableSession> tag in the binding in configuration file.
Another way is to use duplex contracts. In this case the service implements an incoming contract; the client implements a callback contract.
i used duplex services but when the client unexpectedly closes down due to a shutdown or crash, the host is unusable. I need to restart it.
I googled on this issue and i find that when the client unexpectedly closes, the channel is no more usable.
I would like to know how to handle these ususable channels on the host.
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 am using NetNamedPipebinding to communicate between two processes. One of them provides a service at an end point and the other process using DuplexChannel communicates with it.
In some scenario my client process might crash. In those scenarios I need to kill the service process as well. What is the best way to achieve it?
From server side:
I am thinking of having a timer and call the ping method on the callback. If client doesn't respond for ping, I can shut down the service as well. Is there any better solutions?
I am the one who creates the service (process). So I simply passed the process ID of the client process to server (service process) and listen to Process.Exited event.
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 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.
I'm curious to know how I would go about setting up my service to stop cleanly on the server the service will be installed on. For example when I have many clients connecting and doing operations every minute and I want to shut-down the service for maintenance, how can I do this in the "OnStop" event of the service to then let the main service host to deny any new client connections and let the current connections finish before it actually shuts down its services to the client, this will ensure data isn't corrupted on the server as the server shuts down.
Right now I'm not setup as a singleton because I need scalability in the service. So I would have to somehow get my service host to do this independently of knowing how many instances are created of the service class.
You just have to call Dispose on the ServiceHost instance that you create. Once you do that, you will not accept any more clients and the service will continue to finish the operations for clients that are already connected.
I've been wondering the same thing. I found this article which has a pretty in-depth description of how to properly Close/Dispose as ServiceHost or Client.
http://www.danrigsby.com/blog/index.php/2008/02/26/dont-wrap-wcf-service-hosts-or-clients-in-a-using-statement/
In order to accomplish this. I had to create a service reference of itself and in the Windows Service OnStop initiate a new connection and change values in the WCF Service to "shut down" (this was just a shared boolean that the service was online or offline) the service so new clients wouldn't be able to connect (A function the client would call to see if the server was online or offline) and the existing connections would have time to finish up, then after all clients disconnect, continue to shut down the WCF Service using the .Close method.