2011-11-10 3 views
5

È possibile rimuovere un HTTPServletRequest dal thread, dissolvere questo thread (cioè riportarlo nel pool), ma mantenere funzionante la connessione sottostante con il browser, finché non ottengo i risultati da un'operazione che richiede tempo (ad esempio, l'elaborazione di un'immagine)? Quando i dati di ritorno vengono elaborati, un altro metodo dovrebbe essere chiamato in modo asincrono e ricevere la richiesta e i dati come parametri.Implementazione di polling lungo in modo asincrono

In genere, il pooling lungo funziona in modo piuttosto bloccante, in cui il thread corrente non viene risolto, riducendo la scalabilità dell'app lato server, in termini di connessioni simultanee.

+2

Hai provato Servlet 3.0 ed è Servlet Asincrono? http://download.oracle.com/javaee/6/api/javax/servlet/annotation/WebServlet.html#asyncSupported%28%29 Restituisce il thread al pool, ma consente di elaborare alcune operazioni a lungo termine e leggere la richiesta dell'utente –

risposta

2

Sì, è possibile utilizzando le specifiche servlet ver. 3.0. L'implementazione che posso raccomandare è il server Jetty. Vedi here.

5

Sì, è possibile farlo con Servlet 3.0

Di seguito è riportato l'esempio di scrivere l'avviso ogni 30 secondi (non testato).

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

Di seguito è riportato l'esempio da scrivere in base a un evento. È necessario implementare l'alertManager che notifica AlertNotificationHandler quando il client deve essere avvisato.

@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

Cosa succede se l'utente accede alla pagina e l'oggetto asincrono viene creato, ma poi aggiorna la pagina? è un altro oggetto creato? E ora verranno rimandate due richieste? O se si allontanano dalla pagina? La risposta verrà inviata nello spazio esterno? Scusa, sto avendo problemi a sistemarmi la testa! – gmustudent

+0

E nel tuo primo esempio hai un metodo run() all'interno di un altro metodo doGet(). Questo è nuovo per me. Devi farlo in questo modo o puoi separare i metodi? E deve essere chiamato run? – gmustudent