apache,tomcat8,使用jquery和异步servlet的长轮询,每分钟jquery超时

时间:2016-04-15 22:08:22

标签: jquery apache long-polling tomcat8 mod-jk

我正在尝试使用jquery和aysnc servlet添加longpolling,javascript ajax请求每分钟超时,通过创建一个新请求,servlet设置超时10分钟,但jquery ajax在一分钟内超时, 只有当tomcat落后于apache时才会发生这种情况,我使用的是mod_jk连接器。

chrome network tab

的javascript

var MessagePanel ={
    unreadMsg:function(){
        var markup='<div> You have unread messages </div>'
            var my_dialog =$(markup).dialog({
            position:'right'
            ,title:'Unread Messages'    
        });
        my_dialog.dialog('widget').zIndex(25000);   
    },
    newMsg:function(){
        var markup='<div> You have a new message </div>'
            var my_dialog =$(markup).dialog({
            position:'right top'
            ,title:'New Message'    
        });
        my_dialog.dialog('widget').zIndex(25000);   
    }
    ,longPoll:function(channel){
            $.ajax({ 
                url: "/myapp/cometmsg",
                success: function(data){
                    if(data){
                        if('new_message'===data.trim()){
                            MessagePanel.newMsg();
                        }
                    }
                },
                error: function(err) {
                    console.log(" long poll error "+err);
                },
                type: "GET", 
                data: {name:channel,timestamp: new Date().getTime()}
                ,complete:function(){
                    MessagePanel.longPoll(channel)
                }
            });
    }
}

服务器端代码

    public class MessageNotificationServlet extends HttpServlet {

    static Logger  logger= Logger.getLogger(MessageNotificationServlet.class);

    private Queue<AsyncContext> asyncContexts = new ConcurrentLinkedQueue<AsyncContext>(); 
    static BlockingQueue<String> messages = new LinkedBlockingQueue<String>();

    ExecutorService executorService;

    public static void addMessage(String msg){
        try{
            logger.debug("  receiving new msg"+msg);
            messages.add(msg);
            logger.debug("  add new msg"+msg);
        }catch(Exception e){
            throw new RuntimeException(e);
        }
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        executorService=Executors.newSingleThreadExecutor();
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                while(true){
                    try{
                         String message = messages.take();
                         logger.debug(" processing new message  "+message);
                         for(AsyncContext asyncContext :asyncContexts ){
                             try{
                                 if(asyncContext.getRequest().getParameter("name").trim().equals(message)){
                                         String paramName=asyncContext.getRequest().getParameter("name").trim();
                                         String timestamp=asyncContext.getRequest().getParameter("timestamp").trim();
                                         try{
                                             logger.debug(" writing  to   "+paramName +"  "+timestamp);
                                             PrintWriter  printWriter=asyncContext.getResponse().getWriter();
                                             printWriter.println("new_message");
                                             printWriter.flush();
                                             asyncContext.complete();
                                             logger.debug(" completed async to   "+paramName+"  "+timestamp);
                                         }catch(Exception e){
                                             //asyncContexts.remove(asyncContext);
                                             logger.debug(" failed writing to async "+paramName +"  "+timestamp );
                                             logger.error((" async  failed  "+paramName +"  "+timestamp),e);
                                         }
                                     }
                             }catch (Exception e) {
                                 asyncContexts.remove(asyncContext);
                                 logger.debug(" error with asyncontext ",e);
                             }
                         }
                    }catch(Exception e){
                        logger.debug(" error in msg check thread ",e);
                    }
                }
            }
        });
    }
    @Override
    public void destroy() {
        super.destroy();
        messages.clear();
        asyncContexts.clear();
        executorService.shutdownNow();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
        if (req.isAsyncStarted()) {
            logger.debug(" from doget for already started req ");
              response.getWriter().write("asyncResult=" + req.getAttribute("asyncResult"));
        }else {
            String name=req.getParameter("name");
            String timestamp=req.getParameter("timestamp");
            logger.debug(" received new request from  "+name +"  "+timestamp+"  "+new Date());

            AsyncContext  asyncContext=req.startAsync();
            asyncContext.getRequest().setAttribute("start_time", new Date());
            asyncContext.addListener(new AsyncListener() {

                @Override
                public void onTimeout(AsyncEvent event) throws IOException {
                    logger.debug(" timeout occuered  for  " +event.getAsyncContext().getRequest().getParameter("name") +"  "+event.getAsyncContext().getRequest().getParameter("timestamp")+"  "+event.getAsyncContext().getRequest().getAttribute("start_time"));
                    event.getAsyncContext().getResponse().getWriter().write("TIMEOUT");
                    event.getAsyncContext().complete();
                }

                @Override
                public void onStartAsync(AsyncEvent event) throws IOException {
                    logger.debug(" onstart for  " +event.getAsyncContext().getRequest().getParameter("name") +"  "+event.getAsyncContext().getRequest().getParameter("timestamp") +"  "+event.getAsyncContext().getRequest().getAttribute("start_time"));
                }

                @Override
                public void onError(AsyncEvent event) throws IOException {
                    logger.debug(" error occuered  for  " +event.getAsyncContext().getRequest().getParameter("name") +"  "+event.getAsyncContext().getRequest().getParameter("timestamp") +"  "+event.getAsyncContext().getRequest().getAttribute("start_time"));
                    asyncContexts.remove(event.getAsyncContext());  
                }

                @Override
                public void onComplete(AsyncEvent event) throws IOException {
                    logger.debug(" completed  " +event.getAsyncContext().getRequest().getParameter("name")+"  "+event.getAsyncContext().getRequest().getParameter("timestamp") +"  "+event.getAsyncContext().getRequest().getAttribute("start_time"));
                    asyncContexts.remove(event.getAsyncContext());
                }
            });
            asyncContext.setTimeout(TimeUnit.MINUTES.toMillis(10));
            asyncContexts.add(asyncContext);
        }
    }
}

MessagePanel.longPoll是函数,我在页面加载时调用。

0 个答案:

没有答案