« Return to Thread: implementing long poll in grails

Re: implementing long poll in grails

by Dave Crane-7 :: Rate this Message:

Reply to Author | View in Thread

Hi Martin, Robert,

I did solve the original problem that I posted to the list - as I recall, I needed to explicitly call save() on domain classes before going to sleep so that other calls to the server would see them.

However, note my comments that I was doing things the hard way here, and I certainly was! The code I was working on was for the Apress "Comet and Reverse Ajax" book that I wrote last year. In the first couple of chapters, I built a comet implementation from scratch, in order to demonstrate various gotchas, and then go on to demonstrate how much easier it is to use a well-built Comet API, such as Jetty+dojox.comet (for which I didn't have to move over entirely to Dojo code, the demo app used Prototype & Scriptaculous for doing the UI stuff), or DWR (which I know less about, my co-author Phil did that section). I provided a rudimentary Grails plugin for working with the Jetty/Dojo comet stack in Grails, and you can probably download that from the publisher's site, but since then, Mingfai Ma's done a nicer Comet plugin around the same technology - big improvement over my efforts is that it uses Spring singleton abstractions to hold the server-side Comet bus components, whereas I was rather hackily stuffing them in the servlet context (ok for a single VM, but won't scale out).

Mingfai's plugin here: http://www.grails.org/Cometd+Plugin   (gotta love RESTful, intuitive URLs!)

So, Robert's spot-on when he cautions you about messing with HTTP's request/response, and I'd strongly advise you to look at a robust implementation of Comet rather than rolling your own. Clients, servers, network routers, firewalls, etc. all will expect timeouts, and generally get in the way of keeping your connection open, depending on your network, their network, the weather, etc. etc.

The dojo client, for example, understands several approaches to comet, from request streaming to long polling to simple client-side polling. Going from left to right here, the mechanism is getting less efficient, but more likely to survive the presence of proxy servers, firewalls, etc. During the handshake/setup phase, the comet client will fire off test packets in order to assess which is the most efficient communication that can be maintained in a given situation. Caucho's comet stack does the same, I believe, and I guess most of the others do too. Trying to do all this yourself will be painful and error-prone.

Client-side, the Bayeux implementation is pretty nice to work with too - and you can initiate messages on the server too.

HTH, and good luck with whatever you're up to!

Cheers,

Dave

 

2009/7/3 Robert Fischer <robert.fischer@...>
I know what I mean when I say "long polling".  And I agree with you that fanciness with iFrames and browser plugins is overkill for most RIA websites.

However, I think you're substantially underestimating the problems you're going to run into with this "constant connection" approach.  For instance, I guaranty you that you'll end up having to send some kind of keep-alive to clients, because they're really, REALLY going to want to timeout your connections (because, y'know, they expect HTTP to be for a request/response usage).  And your dismissiveness about the browser (and app server's!) active response pool is almost certainly an error.  Active threads are usually measured in the hundreds (see the standard Apache mpm_worker config here[0]), but you're talking about needing one per client, so you're effectively limiting your active client pool to some number in the hundreds—and even that is straining the server!

And this isn't even taking into account the development problems you're going to run into because web development frameworks expect request/response patterns, not request/response...response...response... patterns.  Which you're already encountering.

Worst of all, I really wonder if you're gaining as much as you think you're gaining.  You get effectively the same effect by setting Apache with a high KeepAliveTimeout[1] and KeepAliveRequests[2].  So this may all be for nothing.

On the other hand, you can use a minimized jQuery via Google's CDN for free[3], and that's a bit under 56k (from the get's Content-Length), which is less than a 1 second download for even the slow cell phones.  And that's assuming it's not cached from hitting another site using Google's jQuery. Then, using Google's jQuery and my PeriodicalUpdater[4] (I'd recommend minimizing it) with Apache's KeepAliveTimeout and KeepAliveRequests basically give you the same functionality in a much more HTTP-friendly format.  And that's all simply very compatible JavaScript.

[0] http://httpd.apache.org/docs/2.2/mod/worker.html
[1] http://httpd.apache.org/docs/2.2/mod/core.html#keepalivetimeout
[2] http://httpd.apache.org/docs/2.2/mod/core.html#maxkeepaliverequests
[3] http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery
[4] http://enfranchisedmind.com/blog/posts/jquery-periodicalupdater-ajax-polling/

~~ Robert.


redheat wrote:
Thanks, Robert, for sharing all that expertise.

I have several reasons why I'm pursuing this approach.

The most important one is, as you said,

Don't fight HTTP's nature: work with it.

With this kind of Ajax long polling implementation you don't need any
plugins neither client side nor server side or any extra standards. It's
just plain HTTP, HTML and a bit of Javascript. That's why it works with all
browsers out there, no exceptions. And all server side languages, not just
Java.

Firt of all please take care in using the expression long polling. Long
polling does not mean that you wait a long time between client side polls.
Long polling means that you poll and wait for the server reply, and then
re-poll. What you are proposing is just Ajax periodical update with decay.
With a decay, you are implementing a mix of both approaches. Why don't you
just right away wait until the server has news and replies. There is nothing
against it.

I made a long design study and concluded for myself that Ajax long polling
(i.e., wait for the reply forever) is actually the better way of
implementing Comet style, because traditional comet uses XHRstreaming or
hidden IFrame and stuff, all of which don't work properly in all browsers.

Sorry my best reference is only a German website on long polling (i.e., wait
for reply, then re-poll) but just have a look at the code example if you
care and you'll see how simple it is.
http://wiki.ajax-community.de/tutorial:erste-schritte-mit-comet-longpoll#kompatibilitaet

I'm developing without any plugins because my web app must work with even
the simplest clients like PDAs that don't have any rendering plugins
whatsoever, just a browser. Besides, all the recent browser updates made a
lot of effort speeding up JS rendering. Just look at Apple's recent Safari
which is supposed to beat the JS rendering speed of the other browsers by a
factor of six. I really want to stick to plain JS and don't adopt another
specific rendering plugin which could, in two years, no longer be on the
market. My product is supposed to be long lasting.

Here is an English reference which is second best in my list but please
first look at the code example in the first reference.
http://www.webreference.com/programming/javascript/rg28/

The only drawbacks I've seen so far is that a) in older browsers the number of open requests is limited to two. So you
need to make sure you close requests client side that are not needed.
b) open requests on the server side normally mean an extra threat per
request. But please imagine that a web server must be able to handle
thousands of them, so if a few of them add a second threat for a while
it doesn't make a big difference.

Honestly, if I had a choice I would wait until HTML 5.0 web socket standard
is available in all browsers
http://cometdaily.com/2008/07/04/html5-websocket/
which would provide a standard way of two way communications.

But until then, just plain HTTP.





~~ Robert Fischer, Smokejumper IT Consulting.
Enfranchised Mind Blog http://EnfranchisedMind.com/blog

Check out my book, "Grails Persistence with GORM and GSQL"!
http://www.smokejumperit.com/redirect.html

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email



 « Return to Thread: implementing long poll in grails