users@glassfish.java.net

Re: How to check if the client dropped the connection

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Mon, 28 Sep 2009 13:44:54 -0400

Salut,

aaime74 wrote:
> Hi,
> I'm working on the development of an open source application, GeoServer,
> implementing the Web Map Service specification.
> The specification allows a client to request maps using simple GET
> requests like:
>
> http://sigma.openplans.org:8080/geoserver/wms?WIDTH=431&SRS=EPSG%3A4326&LAYERS=tiger-n
> \
> y&HEIGHT=550&STYLES=&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEP
> \
> TIONS=application%2Fvnd.ogc.se_inimage&BBOX=-74.01697805908182,40.69808217724622,-73.9
> \
> 9567744140603,40.72526393994153
>
> and the client gets back a PNG with a map of the request area.
> No asynchronism is allowed, the protocol is standardized
> (http://portal.opengeospatial.org/files/?artifact_id=1058) and I have no
> controls over the clients (there are tens of them around, both open source
> and proprietary) which are free to make as many request as they like, in
> whatever order the like.
>
> By spec we're forced to use a plain request and response approach, but
> we're experiencing a problem with clients making lots of request as the
> user zooms/pans around: basically a request is made, but the user keeps
> on moving, the client drops the older requests (closing the connection in
> face of
> the server) and makes others.
> Unfortunately in the meantime the older requests are still running, drawing
> a map takes
> time and a lot of memory, for example the above request, which is a
> small one btw, allocates a BufferedImage of 700KB. The memory is
> consumed up until the image is encoded out to the stream, which is also
> the moment we finally figure out the client dropped the connection
> (since writing to the servlet output stream fails).
>
> This is very sub-optimal. Servers like Apache, with cgi, do kill the cgi
> process the moment the connection is dropped, significantly reducing the
> server load both in terms of CPU and memory consumption.
>
> Is there any way to check if the client connection is still open using
> only the standard servlet API?

No, by default if you want to behavior you will need to implement
something like:

   + spawn Thread(s)
   + Block on HttpServletRequest.getInputStream().read()

The issue is you will ends up with one thread per connection blocked on
the read().


> If not, is there any Glassfish specific approach that might work instead?

You can uses the Grizzly Comet Framework for doing that (it's old link
but it describe what it does)

   * http://is.gd/3KWKd

I can feed you with more detailed examples, but as a starter, all you
will need to do is to create a CometHandler

   * http://is.gd/3KX1k

and register it for asynchronous events. When the remote client will
close the connection. the CometHandler.onInterrupt() will be invoked,
telling you the remote connection has been closed.

If you need a solution that works on all Web Server, take a look at:

   * http://atmosphere.dev.java.net

which also support the detection via AtmosphereHandler.

Hope that help.

-- Jeanfrancois





>
> If there is no solution that can be applied at the general servlet
> api level, do you know of any Glassfish specific approach one could use?
> e.g., casting the HttpServletResponse to some Glassfish specific class
> and get some connection information status there?
>
> Cheers
> Andrea
>