2011-11-10 159 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