Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can we detect when a WCF client has disconnected?

Tags:

wcf

Is there any way of finding out when a WCF client has disconnected. Currently the only approach seems to be to wait until a call on the client from the service eventually times out.

I have tried subscribing to the OperationContext.Current.Channel.Faulted event but unfortunately it is never called; my understanding was that this event should be fired when the client disappears. On the other hand, when things close down gracefully OperationContext.Current.Channel.Closed is called.

In our application we only support a single client connection at a time, hence when somebody closes and re-starts the client app it would be nice if the server could be made aware of the the disconnection, tidy up gracefully and then accept another connection.

Yes, clients will disconnect gracefully most of the time, but this can't be guaranteed. Currently the only option seems to be to poll the client and wait for a CommunicationTimeout, which is hardly ideal.

Any suggestions greatly appreciated.

like image 262
Richard Avatar asked Jun 08 '11 14:06

Richard


2 Answers

Theoretically, a service need not have knowledge of client's state. But it can insist on whom to serve for by dictating the authentication needs, concurrency limitation etc.

If you intention is to make sure only one client is served at a time, you can simply opt for Single Concurrency mode.

For example.

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single)] 
public class CalculatorService : ICalculatorConcurrency 

This will ensure only one client request is served at a time. Following link may help you as well.

http://msdn.microsoft.com/en-us/library/ms731193.aspx

EDIT

If you think an user's action of keeping the channel open does disturb the other user's work, it may not be the usual case.

Because each user's call is considered to be a different session. By default WCF calls are considered to be instantiated per call.

If you would like to persist data between user's calls, you may opt for perSession instancing mode.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)] 
public class CalculatorService : ICalculatorInstance 

This would make sure that each user would have an instance of the service which would not inturrupt servicing the other user.

You can set the concurrency mode accordingly i.e Multiple or Reentrant if you wish. Even if the concurrency mode is single, when a response is sent back to the user the service would be ready to serve the next user. It won't wait for the client to close the connection. User's connection would be useful only to keep the session live.

like image 158
SaravananArumugam Avatar answered Sep 22 '22 11:09

SaravananArumugam


You can use IChannelInitializer and hook up Channel Close and Channel faulted events to detect graceful or abrupt closing of the client. Refer to a very nice post on this by Carlos - http://blogs.msdn.com/b/carlosfigueira/archive/2012/02/14/wcf-extensibility-initializers-instance-context-channel-call-context.aspx

like image 27
vibhu Avatar answered Sep 22 '22 11:09

vibhu