The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


Tricks and Tips with Comet part 1: The Browser difference

Posted by jfarcand on August 25, 2009 at 2:39 PM PDT

Writing Comet application is more and more simple, thanks to framework like LIft and Atmosphere. On the Client side, the difference between Safari, Opera, Firefox, IE and Chrome can make your application completely unresponsive or broken. Of course, there is some tricks to make it work.

First, if you are new to Comet, I recommend you take a look at this introduction. For this serie, I will use my new project called Atmosphere, which is a framework for writing portable Comet and REST applications. I always use Firefox for developping, and recently I've got surprise when I 've realized all Atmosphere's sample did work on WebKit (Chrome, Safari) and Opera.

First, to make Safari works properly with the Comet technique called http streaming or forever frame, make sure, on the server side, you set the content-type properly and disable the cache.

        res.setContentType("text/html");
        res.addHeader("Cache-Control", "private");
        res.addHeader("Pragma", "no-cache");

That works well with GlassFish and Jetty...but not Tomcat. Why? Because both Jetty and GlassFish append the charset for you all the time, and Tomcat don't. Safari seems to not like it. So the proper code consist of:

        res.setContentType("text/html;charset=ISO-8859-1");
        res.addHeader("Cache-Control", "private");
        res.addHeader("Pragma", "no-cache");

Note that Firefox will work without the above, same for IE. Now the above will make the Comet technique called Long-polling working, but http streaming will still be broken on Safari. Why? Because when you suspend the response, if you don't fill out Safari with some data (~2k), all events that will happen once the response has been suspended will be written by the server, but never read/displayed in Safari, Chrome, IE and Opera.  As an example, I always output the following junk before I suspend a response in Atmosphere:

    private final static String JUNK = "<!-- Comet is a programming technique that enables web " +
                    "servers to send data to the client without having any need " +
                    "for the client to request it. -->\n";

            ......

            for (int i =0; i< 10; i++){
                res.getWriter().write(JUNK);
            }
            res.getWriter().flush();

If you are using Atmosphere REST module using Scala, you also need to do something like:

    var JUNK : String = "<!-- Comet is a programming technique that enables web " +
                    "servers to send data to the client without having any need " +
                    "for the client to request it. -->\n"

    @Suspend
    @GET
    @Produces(Array("text/html;charset=ISO-8859-1"))
    def suspend() = {
        var s = new StringBuilder()
        for (i <- 0 to 10){
            s.append(JUNK)
        }
        s.toString()
    }

Quite paintfull but until websocket are widely adopted (will they?), you will need a little bit of hacking. But once you know them, that should be easy. Client library like JQuery and Dojo's Cometd implementation already do that for you, but if are using pure javascript (or iframe for the http streaming support), make sure you recall that simple tip. You can download many Comet samples from here. They work on any Java WebServer.

If you have any questions, post them on users@atmosphere.dev.java.net, use Nabble or or tweet them.

technorati:

 

 

 

 

 

 

Related Topics >> Blogs      Glassfish      Web Applications      
Comments
Comments are listed in date ascending order (oldest first)

Now the above will make the

Now the above will make the Comet technique called Long-polling working, but http streaming will still be broken on Safari. ed hardy,

No :-)

No, the trick will works for both techniques. Just go to http://atmosphere.dev.java.net and download any sample using streamin. They will works :-)