Question

I have followed Tomek Janczuk's Pub/sub sample using HTTP polling duplex WCF channel but I've noticed that when a client disconnects by closing the browser the service does not notice on the next callback. I would have expected an exception or something to say that the endpoint was not there any longer.

How can you know when a client is gone, so as to stop publishing to that client?

Was it helpful?

Solution

It seems there's one unsatisfactory, albeit simple solution: If the client callback times out, don't call it again.

In my system I've also implemented a manual "check" call - every n seconds the server calls a parameterless method over the callback channel for each registered client, just to see if the client is still there. I'm starting to wonder if that really was a good idea - I've got a new problem where a callback timeout keeps occurring because I've suspended the client in the debugger.

OTHER TIPS

To know for sure: impossible.

When a TCP connection is closed (underlying an HTTP call), a special TCP message is sent to the server - FIN packet. Although HTTP is stateless, underlying TCP connection is stateful and with keep alive, underlying TCP connection usually stays open. If client is disposed, TCP connection is closed and normally a message sent to the server. But if it crashes or its network is disconnected, it would not have the time to do this. So in one word, you can never be sure.

Here for more info.

Its hard, almost impossible (cause of limited SL duplex capabilities). we have implemented a list of users in our service, and we have added a property "IsDisconnected" and LastCommunicationTime, once WCF service gets a timeout when tries to add a message in user's Outgoing-Message-Queue, and fails, and throws an exception of timeout. we mark "IsDisconnecte=true" and next time don't try to send the message to that user.

Another thread keeps looking at that and if it notice that the LastCommunicationTime has been exceeded by a value of time and IsDisconnected=true, it removes the user from the list, unless the same user tries to get connected again within this time period (which we identify by its UserId).

There are so many things we did manually to handle this problem as it was making the WCF service so much busy.

I faced this problem and created a thread that removes disconnected clients with the following code. It works fine but drops the disconnected client from the client list after 10-15 minutes (which was ok for me).

    new Thread(new ThreadStart(() =>
    {
        while (SilverlightClients != null)
        {
                lock (SilverlightClients)
                {
                    SilverlightClients = SilverlightClients.Where(d => (d.Callback as IContextChannel).State != CommunicationState.Opened).ToList();
                }

            Thread.Sleep(1000);
        }
    })) { Name = "Thread Remove Disconnected Clients" }.Start();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top