2011-11-10 11 views
5

Czy można odjąć HTTPServletRequest od jego wątku, rozpuścić ten wątek (np. Przywrócić go do puli), ale utrzymywać podstawowe połączenie z przeglądarką, dopóki nie otrzymam wyników od czasochłonnej operacji (powiedzmy, przetwarzania obrazu)? Kiedy przetwarzane są dane zwracane, inna metoda powinna być wywołana asynchronicznie i otrzymać żądanie, a także dane jako parametry.Wdrażanie długiego sondowania w asynchronicznej modzie

Zwykle długie funkcje łączenia w ładny sposób blokowania, w którym bieżący wątek nie jest rozpuszczany, co zmniejsza skalowalność aplikacji po stronie serwera pod względem równoczesnych połączeń.

+2

Czy próbowałeś Servlet 3.0 i Asynchronous Servlet? http://download.oracle.com/javaee/6/api/javax/servlet/annotation/WebServlet.html#asyncSupported%28%29 Zwróci twój wątek do puli, ale zezwoli na przetworzenie długotrwałej operacji i przeczytaj żądanie użytkownika –

Odpowiedz

2

Tak, jest to możliwe za pomocą Servlet spec ver. 3.0. Wdrożenie Mogę polecić serwer Jetty. Zobacz here.

5

Tak, można to zrobić z Servlet 3.0

Poniżej próbka napisać alert co 30 sek (nie testowane).

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

Poniżej znajduje się próbka do napisania na podstawie zdarzenia. Należy zaimplementować alertManager, który powiadamia AlertNotificationHandler, gdy klient musi być ostrzeżony.

@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

Co się stanie, gdy użytkownik wejdzie na stronę i zostanie utworzony obiekt asynchroniczny, ale odświeży stronę? to jest inny obiekt stworzony? A teraz dwie prośby zostaną odesłane? A co, jeśli odejdą od strony? Czy odpowiedź zostanie wysłana do kosmosu? Przepraszam, że mam kłopoty z owinięciem głowy! – gmustudent

+0

I w twoim pierwszym przykładzie masz metodę run() wewnątrz innej metody doGet(). To dla mnie nowe. Czy musisz to robić w ten sposób, czy możesz oddzielić metody? I czy trzeba to nazwać runem? – gmustudent

Powiązane problemy