users@grizzly.java.net

Re: Problem with comet-based web app -- Streaming

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Mon, 03 Nov 2008 10:36:40 -0500

Salut,

Richard Corbin wrote:
> Ohhh man, your lucky , I've just spent about a week dealing with some of
> the streaming issues with Client side JS :).

yes that's quite difficult.

I hope I can save you some
> time and a few mild strokes :). I'm gonna forward this to the mailing
> list so I can get some input, maybe even start a muse or someone that's
> been there can enlighten me.. Below is what I found and the conclusion
> that I've come to. The problems with streaming lie in the twisted heap
> of wires know as Cross Browser JS.
>
> 1. if your using FF and you try to modify the document object while a
> stream is open it will terminate the connection. Don't use
> document.write() .. this took me about 1 full day to figure out and it
> was REALLY frustrating (All JS is frustrating as debuging is so
> cryptic). I believe this is a bug in FF. I have found a few in IE as well.

I wasn't aware of such issues....but I'm not really good with JavaScript


>
> 2. I use Prototype, as it simply rocks :). seriously though, its
> indispensable for coding larger client side segments in JS. I don't use
> Jmaki, but I think that's where your problems are.. I'm sure it has a
> wrapper for the XMLHttpRequest object and it was not intended to handle
> streaming. actually XMLHttpRequest is intended to handle streaming but
> MS imlementations of it fail to do so. Anyway about prototype, I had to
> modify it a bit to deal with the streaming comet, and really at the end
> of the day you might as well write your own implementation of
> XMLHttpRequest as the onInteractive ( if(readyState==3) ) method of the
> Ajax "Class" has NO abort(); method...
>
> 3. Streaming is troublesome, since IE wont let you read the object until
> readyState=4 , so essentialy, what you have to do is... either use some
> iframe voodoo ( which shows the spinner, i personaly feel thats
> unacceptable) or use a technique that, does a dissconnect/reconnect
> after every push. in your onEvent(CometEvent e)... add this after the
> flush(), <CometContext>.removeCometHandler(this); .

yes, this is the 'long-polled' technique in Comet.


  Then, in your client
> specify a reconnect after every response is recived you will reconnect
> and wait for the next push... There are other solutions, and Im
> exploring them as I type this.. such as using a flash applet or Java
> applet for client/server communications.
>
> The Flash Applet method has problems (flaky actually with v9) and the
> Java applet method works great but would require more users to download
> a plugin... So im working on a mesh of systems that will detect, install
> and try the various "Drivers" ( my silly term :) ) for the clients. ie6
> is still 24% of the market so it has to be addressed. anyway, I look
> forward to uploading my work in this area shortly.
>
> P.S.
> Im having little luck with any JS methods + IE6 regaurdless but i'm
> under Linux / Wine , so .. who knows whats going on :) If you come up
> with any cool ideas feel free to share.

Are you pushing back some blank data on suspended connection? IE have
some trouble with streaming/long-polling if you don't send back some
data (while space/whatever) before suspending the connection.

Thanks

-- Jeanfrancois



>
> --Richard
>
>
>
> ------------------------------------------------------------------------
> *From:* Hiram Coffy <hiram.coffy_at_pb.com>
> *To:* Richard Corbin <igf1_at_yahoo.com>
> *Sent:* Friday, October 31, 2008 7:13:47 PM
> *Subject:* RE: Problem with comet-based web app **SOLVED**
>
> Hello Richard,
>
>
>
> Remember me, I’d like to peak your brain for a moment. I am seeing a set
> of peculiar behaviors with my simple comet web app. I am using a jMaki
> client that makes a async call to my comet servlet. 1) I noticed that
> unless I call close on the connection the data does not get flushed out
> to the client. Calling flush appears not to have the desired effect. 2)
> It appears that the connection cannot be held open regardless of what
> the server does.
>
>
>
> I don’t know if you have any experience with jMaki. Any help would be
> much appreciated.
>
>
>
> Noticed that my code is setup according to Sun’s official tutorial. But
> I believe in the end the wiring is similar to the approach you recommended.
>
>
>
> Relevant bits of code:
>
>
>
> *Client:*
>
> jmaki.subscribe("/bn/refresh/*", function(args) {
>
>
>
> *jmaki.doAjax({*method: "GET",
>
> url: "RefreshServlet",
>
> callback: function(_req) {
>
> var tmp = _req.responseText;
>
> var obj = eval("(" + tmp + ")");
>
>
>
> jmaki.publish('/bn/setValues', obj);
>
> document.getElementById('counter').innerHTML ="<div
> id='counter'><b>" + new Date().toString() + "</b></div>";
>
> }
>
> });
>
> });
>
>
>
> *Server:*
>
> * @Override*
>
> * public void init(ServletConfig config) throws ServletException {*
>
> …
>
>
>
> /* Configure this web app server to work in async mode using
> comet engine */
>
> ServletContext ctx = config.getServletContext();
>
> contextPath = ctx.getContextPath();
>
>
>
> CometEngine engine = CometEngine.getEngine();
>
> CometContext cctx = engine.register(contextPath);
>
>
>
> //cctx.setExpirationDelay(30 * 1000);
>
> * cctx.setExpirationDelay(-1); //Doesn’t seem to make any
> difference*
>
> ..
>
> }
>
>
>
> *_at_Override*
>
> * protected void doGet(HttpServletRequest request,
> HttpServletResponse response)*
>
> throws ServletException, IOException {
>
>
>
> registerHandler(response, request);
>
> processRequest(request, response);
>
> }
>
>
>
> * private void registerHandler(HttpServletResponse response,
> HttpServletRequest request)*
>
> throws IllegalStateException {
>
> HttpSession session = request.getSession();
>
> ….
>
>
>
> if ( session.getAttribute(requestURL) == null) {
>
> RefreshHandler handler = new RefreshHandler();
>
> handler.attach(response);
>
>
>
> CometEngine engine = CometEngine.getEngine();
>
> CometContext context = engine.getCometContext(contextPath);
>
>
>
> try {
>
> context.addCometHandler(handler);
>
> session.setAttribute(requestURL, true );
>
> } catch (IllegalStateException ex) {
>
> …
>
> }
>
> }
>
> }
>
>
>
> * protected void processRequest(HttpServletRequest request,
> HttpServletResponse response)*
>
> throws ServletException, IOException {
>
>
>
> /* Notify RefreshHandler */
>
>
>
> CometEngine engine = CometEngine.getEngine();
>
> CometContext<?> cctx = engine.getCometContext(contextPath);
>
> cctx.notify(null);
>
>
>
> refreshComboBox(response);
>
> }
>
>
>
> * private class RefreshHandler implements
> CometHandler<HttpServletResponse> {*
>
>
>
> private HttpServletResponse response;
>
>
>
> public void onEvent(CometEvent event) throws IOException {
>
> if (CometEvent.NOTIFY == event.getType()) {
>
>
>
> refreshComboBox(response);
>
>
>
> // commented out the resume if it is Http Streaming
>
> //event.getCometContext().resumeCometHandler(this);
>
> }
>
> }
>
> …..
>
> }
>
>
>
> * void refreshComboBox(HttpServletResponse response) throws IOException{*
>
>
>
> ProvisioningDocLocatorBeanWS provBean = new
> ProvisioningDocLocatorBeanWS();
>
>
>
> PrintWriter writer = response.getWriter();
>
> try {
>
>
>
> writer.write(provBean.getProvisioningDocs());
>
> * writer.flush(); //Does not flush data to the client*
>
>
>
> } catch (JSONException jex) {
>
> logger.error(jex.getMessage(), jex);
>
> } finally {
>
> * writer.close(); //Unless I call close data does not get
> flushed out to client*
>
> logger.info <http://logger.info>("Refreshed Client :" +
> System.currentTimeMillis());
>
> }
>
> }
>
>
>
>
>
> *From:* Richard Corbin [mailto:igf1_at_yahoo.com]
> *Sent:* Friday, October 31, 2008 9:26 AM
> *To:* Hiram Coffy
> *Subject:* Re: Problem with comet-based web app **SOLVED**
>
>
>
> Hey no problem man, let me know if I can help.
>
> -- Richard
>
>
>
> ------------------------------------------------------------------------
>
> *From:* Hiram Coffy <hiram.coffy_at_pb.com>
> *To:* Richard Corbin <igf1_at_yahoo.com>
> *Sent:* Friday, October 31, 2008 7:31:34 AM
> *Subject:* FW: Problem with comet-based web app **SOLVED**
>
> Hello Richard,
>
>
>
> Thanx much for all your pointers. I hadn’t realized that you had replied
> to my post until this morning. I am still getting use to getting around
> in the forum.
>
> Apologies for the belated response. Your contributions were very helpful
> to me. I believe I have the mechanics of this technique down, I just
> needed clarifications on implementation.
>
>
>
> Best Regards,
>
>
>
> Hiram
>
>
>
> *From:* Hiram Coffy
> *Sent:* Thursday, October 30, 2008 4:23 PM
> *To:* 'users_at_grizzly.dev.java.net'
> *Subject:* RE: Problem with comet-based web app
>
>
>
> Salut Jeanfrancois,
>
>
>
> Thank you very much for being so
> responsive. Your answers to step 2 and 6 got me unstuck. I appreciate your help.
>
>
>
> 2) API: What compatible comet api should I compile the source code against?
>
>
>
> If you plan to deploy against v2ur2, you need to build against the API
>
> that ship with v2. Hence, in your classpath, you need to add:
>
>
>
> ${glassfish.home}/lib/appserv-rt.jar.
>
>
>
> 6)Last question: Does the app server come bundled with the comet api
>
>
>
> yes, in v2: com.sun.enterprise.web.connector.grizzly.comet.*
>
> in v3 and grizzly standalone: com.sun.grizzly.comet
>
>
>
>
>
> Keep up the great work!
>
> Regards,
>
>
>
> Hiram
>
>
>
> A+
>
>
>
>
>
> *From:* Hiram Coffy
> *Sent:* Wednesday, October 29, 2008 12:57 PM
> *To:* 'users_at_grizzly.dev.java.net'
> *Subject:* Re: Problem with comet-based web app
>
>
>
> Hi all,
>
>
>
> I am still struggling with getting my comet-based servlet to work. Any
> help would be much appreciated
>
>
>
> I guess what would be helpful for me is a simple step-by-step procedure.
> So far, what I have found is scattered and fragmented bits and pieces of
> information, critical details appear to be glossed over.
>
>
>
> I suppose I can boil down my request to the following set of questions:
>
> 1) APP SERVER: What do I need to get comet-based servlet working? e.g.
> glassfish V2UR2 with comet support enabled.
>
>
>
> 2) API: What compatible comet api should I compile the source code with?
>
>
>
> 3) API DOWNLOAD: Where do I download the API from?
>
>
>
> 4) CLASSPATH: Do I copy the API to ${as.home}/lib for example
>
>
>
> 5) TEST: How do I positively verify that comet support is indeed enabled?
>
>
>
> 6)Last question: Does the app server come bundled with the comet api
>
>
>
> *From:* Hiram Coffy
> *Sent:* Sunday, October 26, 2008 5:39 PM
> *To:* 'users_at_grizzly.dev.java.net'
> *Subject:* Problem with comet-based web app
>
>
>
> Hello Jean-Francois,
> Let me start by thanking you for all your good work on the Grizzly/comet
> front. Kudos!
>
> I wrote a simple comet app based on the tutorial found at:
> http://docs.sun.com/app/docs/doc/820-4496/ggrgt?a=view.
>
> I get the following exception when a request is received by my servlet:
> java.lang.IllegalStateException: Make sure you have enabled Comet or
> make sure the Thread invoking that method is the same a the request Thread.
> at com.sun.grizzly.comet.CometContext.addCometHandler(CometContext.java:263)
> at com.sun.grizzly.comet.CometContext.addCometHandler(CometContext.java:311)
> ....
>
> I have already combed through your blogs. I have tried all the
> suggestions that I have come across. So far, i haven't had any success.
> I noticed a peculiar behavior with my glassfish instance; whether
> <property name="cometSupport" value="true"/> is added to domain.xml or
> not seems to make not a bit of a difference.
>
> I have made sure to bounce the server every time i make a change to
> domain.xml to ensure that the changes will be recognized. I have tried
> several experiments with the "cometSupport" property added and removed
> from domain.xml. I ave tried similar experiments with <property
> name="proxiedProtocols" value="ws/tcp"/> I have even enabled the flag
> through the command line using "asadmin set
> server.http-service.http-listener.http-listener-1.property.cometSupport=true"
>
> Relevant environment information:
> Sun Java System Application Server 9.1 (build b58g-fcs) (GlassfishV2)
>
> excerpt from domain.xml:
> ....
> <http-listener acceptor-threads="1" address="0.0.0.0"
> blocking-enabled="false" default-virtual-server="server" enabled="true"
> family="inet" id="http-listener-1" port="8080" security-enabled="false"
> server-name="" xpowered-by="true">
> <property name="proxiedProtocols" value="ws/tcp"/>
> <property name="cometSupport" value="true"/>
> </http-listener>
> ....
>
> excerpt from app server output console:
> ....
> WEB0302: Starting Sun-Java-System/Application-Server.
> Enabling Grizzly ARP Comet support.
> WEB0712: Starting Sun-Java-System/Application-Server HTTP/1.1 on 8080
> ....
>
> excerpt from web.xml
> ...
> <servlet>
> <servlet-name>RefreshServlet</servlet-name>
> <servlet-class>package.RefreshServlet</servlet-class>
> <load-on-startup>0</load-on-startup>
> </servlet>
> ...
>
> The following bit of code registers the handler and is invoked only
> once, upon receipt of first request.
> private void registerHandler(HttpServletResponse response)
> throws IllegalStateException{
> if (oneShot) {
> RefreshHandler handler = new RefreshHandler();
> handler.attach(response);
>
> CometEngine engine = CometEngine.getEngine();
> CometContext context = engine.getCometContext(contextPath);
>
> try{
> context.addCometHandler(handler);
> oneShot = false;
> }catch(IllegalStateException ex){
> logger.error(ex.getMessage(), ex);
> throw ex;
> }
> }
> }
> Two questions:
> 1) Any suggestions?
> 2) How can I positively tell that comet support is indeed enabled?
>
>
>
>
>
>