2011-11-10 36 views
5

Có thể lấy HTTPServletRequest ra khỏi chuỗi của nó, giải thể luồng này (nghĩa là đưa nó trở lại hồ bơi), nhưng giữ kết nối cơ bản với trình duyệt đang hoạt động, cho đến khi tôi nhận được kết quả từ một hoạt động tốn thời gian (nói, xử lý một hình ảnh)? Khi dữ liệu trả về được xử lý, một phương thức khác sẽ được gọi là không đồng bộ và được cung cấp yêu cầu cũng như dữ liệu dưới dạng tham số.Thực hiện bỏ phiếu dài theo cách không đồng bộ

Thông thường, các chức năng tổng hợp dài theo kiểu bị chặn khá tốt, trong đó luồng hiện tại không bị giải thể, làm giảm khả năng mở rộng của ứng dụng phía máy chủ, về các kết nối đồng thời.

+2

Bạn đã thử Servlet 3.0 và Servlet không đồng bộ không? http://download.oracle.com/javaee/6/api/javax/servlet/annotation/WebServlet.html#asyncSupported%28%29 Nó sẽ trả lại luồng của bạn tới hồ bơi, nhưng cho phép xử lý một số hoạt động lâu dài và đọc yêu cầu của người dùng –

Trả lời

2

Có, có thể sử dụng thông số kỹ thuật Servlet ver. 3.0. Thực hiện tôi có thể đề nghị là máy chủ Jetty. Xem here.

5

Có, bạn có thể thực hiện việc này với Servlet 3.0

Dưới đây là mẫu để viết cảnh báo sau mỗi 30 giây (không được kiểm tra).

@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); 
} 
} 

Dưới đây là mẫu viết dựa trên sự kiện. AlertManager phải được thực hiện để thông báo cho AlertNotificationHandler khi máy khách phải được cảnh báo.

@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

Điều gì sẽ xảy ra nếu người dùng truy cập trang và đối tượng async được tạo nhưng sau đó họ làm mới trang? là một đối tượng khác được tạo ra? Và bây giờ sẽ có hai yêu cầu được gửi lại? Hoặc điều gì sẽ xảy ra nếu họ điều hướng khỏi trang? Liệu phản ứng sẽ được gửi đến không gian bên ngoài? Xin lỗi, tôi đang gặp rắc rối khi quấn đầu quanh cái này! – gmustudent

+0

Và trong ví dụ đầu tiên của bạn, bạn có phương thức run() bên trong phương thức khác doGet(). Đó là điều mới mẻ đối với tôi. Bạn có phải làm theo cách này hay bạn có thể tách riêng các phương pháp? Và nó phải được gọi là chạy? – gmustudent

Các vấn đề liên quan