2011-11-10 74 views
5

是否有可能采取从它的线程为HttpServletRequest远,化解这个线程(即把它带回池),但保持与浏览器工作的基本连接,直到我得到的结果从耗时的操作(例如处理图像)?处理返回数据时,应该异步调用另一个方法,并将请求和数据作为参数提供。实现长轮询以异步方式

通常,在一个相当阻断方式,在那里当前线程不溶解,从而降低了服务器端应用程序的可扩展性,在并发连接方面长池的功能。

+2

您是否尝试过Servlet 3.0,它是异步Servlet? http://download.oracle.com/javaee/6/api/javax/servlet/annotation/WebServlet.html#asyncSupported%28%29它将你的线程返回到池中,但允许处理一些长期经营读取用户的请求 –

回答

2

是的,有可能使用Servlet规范版本。 3.0。我可以推荐的实现是Jetty服务器。请参阅here

5

是的,你可以从Servlet 3.0

下面做,这是写的警报每隔30秒的样品(未测试)。

@WebServlet(async =“true”) 
public class AsyncServlet extends HttpServlet { 

Timer timer = new Timer("ClientNotifier"); 

public void doGet(HttpServletRequest req, HttpServletResponse res) { 

    AsyncContext aCtx = request.startAsync(req, res); 
    // Suspend request for 30 Secs 
    timer.schedule(new TimerTask(aCtx) { 

     public void run() { 
      try{ 
        //read unread alerts count 
       int unreadAlertCount = alertManager.getUnreadAlerts(username); 
        // write unread alerts count 
    response.write(unreadAlertCount); 
      } 
      catch(Exception e){ 
       aCtx.complete(); 
      } 
     } 
    }, 30000); 
} 
} 

以下是基于事件编写的示例。必须实施alertManager,通知AlertNotificationHandler何时必须提醒客户端。

@WebServlet(async=“true”) 
public class AsyncServlet extends HttpServlet { 
public void doGet(HttpServletRequest req, HttpServletResponse res) { 
     final AsyncContext asyncCtx = request.startAsync(req, res); 
     alertManager.register(new AlertNotificationHandler() { 
        public void onNewAlert() { // Notified on new alerts 
         try { 
           int unreadAlertCount = 
             alertManager.getUnreadAlerts(); 
           ServletResponse response = asyncCtx.getResponse(); 
           writeResponse(response, unreadAlertCount); 
           // Write unread alerts count 
         } catch (Exception ex) { 
           asyncCtx.complete(); 
           // Closes the response 
         } 
        } 
     }); 
    } 
} 
+1

如果用户进入该页面,并异步对象被创建,会发生什么,但他们刷新页面?是另一个创建的对象?现在两个请求会被发送回去吗?或者如果他们离开页面?答案是否会发送到外层空间?抱歉,我无法绕过这个包裹! – gmustudent

+0

在你的第一个例子中,你有另一个方法doGet()内的方法run()。这对我来说是新的。你是否必须这样做,或者你能分开这些方法?它是否必须被称为运行? – gmustudent