Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How one can know if the client has closed the connection

I've been playing with the new Servlet 3.0 async features with Tomcat 7.0.4. I found this Chat Application, that lets clients hang on GET request to get message updates. This is working just fine when it comes to receiving the messages.

The problem arises when the client is disconnected i.e. the user closes the browser. It seems that the server does not raise IOException, even though the client has disconnected. The message thread (see the source code from link above) is happily writing to all stored AsyncContext's output streams.

Is this a Tomcat bug? or am I missing something here? If this is not a bug, then how I'm supposed to detect whether the client has closed the connection?

like image 368
SS3 Avatar asked Nov 23 '10 06:11

SS3


People also ask

How do I know if my client socket is closed?

isClosed() tells you whether you have closed this socket. Until you have, it returns false.

How can I tell when a server is closing the connection?

If the server closes the connection after sometime ,how can the client know that the server has closed the connection. [Thomas] You could try periodically pinging the server, and if you get "timed out", then you know that the connection has terminated.

How do you determine if a TCP client has been disconnected?

In TCP there is only one way to detect an orderly disconnect, and that is by getting zero as a return value from read()/recv()/recvXXX() when reading. There is also only one reliable way to detect a broken connection: by writing to it.

What happens when a client closes a socket?

The client program closes the socket using shutdown() or close() . When this happens, TCP will send a FIN packet to your server. This will show up as a closed socket in your server when you try to read beyond the last byte of data sent by the client. The next read() will probably throw an exception or error condition.


1 Answers

The code there at line 44 - 47 is taking care of it,

} catch(IOException ex) {
    System.out.println(ex);
    queue.remove(ac);
}

And here too at 75 - 83, using timeout thingie,

req.addAsyncListener(new AsyncListener() {
    public void onComplete(AsyncEvent event) throws IOException {
        queue.remove(ac);
    }

    public void onTimeout(AsyncEvent event) throws IOException {
        queue.remove(ac);
    }
});

EDIT: After getting a little more insight.

  1. Tomcat 7.0.4 is still in beta. So, you can expect such behaviour
  2. I tried hard but can't find the method setAsyncTimeout() in the doc, neither here, nor here. So, I think they dropped it completely in the final version due to some unknown valid reason
  3. The example states, "why should I use the framework instead of waiting for Servlet 3.0 Async API". Which infers that its written before the final thingie

So, what I can say, after combining all these fact, that you are trying to work with the thing that is broken in a sense. That also, may be, the reason for different and weird results.

like image 178
Adeel Ansari Avatar answered Nov 14 '22 22:11

Adeel Ansari