Is there a WCF Client event on disconnection/faulted? - wcf

I am using netTcpBinding in WCF and I would like to know, on the client side, when it disconnects or when its channel state goes to faulted, so that I can reconnect with the server.
The idea is creating a keep alive using channel events. I know it is possible to know that the client disconnected/went into faulted state in the server side using Channel.Faulted event. That way I can remove any subscriptions the client had on the server. However, I cannot reconnect the client on the server side. And that's exactly what I would like to do.

Related

WCF client becomes unusuable after internet is lost and reconnected

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.

WCF check is client callback contract is alive

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.

Closing channel on client side after every call to service application

I've started working on a client-server distributed application using WCF. The clients should also send requests to the server, therefore I chose to implement duplex operations using the NetTcpBinding since all the clients will b on the same intranet.
On the server side, for the service class that implements the server contract I use these settings
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false)]
Every time a client is initialized, I'm creating an instance of the proxy class generated by adding the service using 'Add service reference' option in Visual Studio. After the proxy is initialized, I send a Connect message to the server:
_proxy.InnerChannel.Faulted += new EventHandler(InnerChannel_Faulted);
_proxy.InnerChannel.Closing += new EventHandler(InnerChannel_Closing);
//send a connect message to the server
_proxy.ClientConnected(ClientHostName, Version, ClientID, ClientIP);
Now the server has a reference to the connected client, by using
OperationContext.Current.GetCallbackChannel<IClientEvents>()
This is pretty straight forward, nothing fancy. However, I'm having a bit of trouble with making the client reconnecting to the server after the server went online. In my scenario, I will have up to 50-100 clients connected to the server and they will rarely communicate with the server, let's say in average, 1 request per hour.
What I want to achieve is to have the client "hanging" while the is offline, for this I try to reinitialize the communication channel on the client side every time the channel ends up in Faulted state, which works ok. But when I try to close the server, I get the following message
This could be because a client failed to close a sessionful channel within the required time.
I'm now struggling to find the most appropriate implementation for my scenario:
Not closing the channel after the service call. This way the client will always try to recreate the channel once the connection with the server is down (e.g. interval of 1 min). Doesn't make much sense to keep the channel opened all this time though, so I'm not that sure about this approach.
Closing the channel after each call and recreate when making a new call to the server. This works fine when making service calls, but what happens if the server wants to send a notification the client? The callback reference on the server side will not be valid anymore, I'd have to wait for the client to send a new connect message to get the new callback reference, right? In this case, should I regularly have a different call similar to a Ping() to the server in order to ensure that the server can always contact the client?
I'm still reading materials on WCF duplex operations, just can't decide which approach is better so that I don't run into problems later on.
Thanks for your advice!

WCF - How do I know when a connection is lost from server (service) side? (for ex: client crashes may be because of some fatal exception)

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.

wcf and duplex communication

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.