users@grizzly.java.net

Re: LongPollingServlet can only connect one at a time

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Fri, 18 Apr 2008 15:01:58 -0400

Hi,

Dan Dubois wrote:
> Hi,
>
> I am using Glassfish v2 U1 with cometSupport = true in my domain.xml file.
>
> I have changed the LongPollingServlet a bit to experiment:
>
> When http://localhost:8080/chat/long_polling is called, the servlet
> notifies all the attached ContextHandlers by outputting text saying
> "success".
>
> However if I open multiple browser windows, I can only seem to attach
> one ContextHandler at a time. When the connection of the first handler
> expires, only then will the second connect.
> http://localhost:8080/chat/long_polling?attach=true attaches a
> ContextHandler
>
> Why is that? I am sure this is a school boy error...

The W3C recommends that a browser opens 2 connections maximum to the
same host...so if you have multiples tab, then your browser will loose
its 2 connections (because they are long polled :-)).

This is configurable with Firefox, and I know IE 8 will allow a max of 8...

The solution is to multiplex your long polling connection on the client
side...not simple using javascript (at least for me).

Thanks

-- Jeanfrancois



>
> Thanks,
> Dan
>
> package com.sun.grizzly.example.comet;
>
> import java.io.IOException;
> import java.io.PrintWriter;
>
> import javax.servlet.ServletConfig;
> import javax.servlet.ServletContext;
> import javax.servlet.ServletException;
> import javax.servlet.http.HttpServlet;
> import javax.servlet.http.HttpServletRequest;
> import javax.servlet.http.HttpServletResponse;
>
> import com.sun.enterprise.web.connector.grizzly.comet.CometContext;
> import com.sun.enterprise.web.connector.grizzly.comet.CometEngine;
> import com.sun.enterprise.web.connector.grizzly.comet.CometEvent;
> import com.sun.enterprise.web.connector.grizzly.comet.CometHandler;
>
> public class LongPollingServlet extends HttpServlet {
>
> private class CounterHandler implements
> CometHandler<HttpServletResponse> {
>
> private HttpServletResponse response;
>
> @Override
> public void onEvent(CometEvent event) throws IOException {
> if (CometEvent.NOTIFY == event.getType()) {
> PrintWriter writer = response.getWriter();
> writer.write(" successful ");
> writer.flush();
> }
> }
>
> @Override
> public void onInitialize(CometEvent event) throws IOException { }
>
> @Override
> public void onInterrupt(CometEvent event) throws IOException {
> event.getCometContext().removeCometHandler(this);
> }
>
> @Override
> public void onTerminate(CometEvent event) throws IOException { }
>
> @Override
> public void attach(HttpServletResponse attachment) {
> this.response = attachment;
> }
> }
> private String contextPath;
>
> @Override
> public void init(ServletConfig config) throws ServletException {
> ServletContext context = config.getServletContext();
> contextPath = context.getContextPath() + "/long_polling";
>
> CometEngine engine = CometEngine.getEngine();
> CometContext cometContext = engine.register(contextPath);
> cometContext.setExpirationDelay(30 * 1000);
> }
>
> @Override
> protected void doGet(HttpServletRequest req, HttpServletResponse res)
> throws ServletException, IOException {
>
> CometEngine engine = CometEngine.getEngine();
> CometContext context = engine.getCometContext(contextPath);
> if ("true".equals(req.getParameter("attach"))) {
> CounterHandler handler = new CounterHandler();
> handler.attach(res);
> context.addCometHandler(handler);
> } else {
> context.notify(null);
> }
> }
>
> @Override
> protected void doPost(HttpServletRequest req, HttpServletResponse res)
> throws ServletException, IOException {
> }
> }
>
>
>