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!