2014-11-11 9 views
8

ho appena iniziato a giocare con Server Events e mi sono imbattuto in un messaggio di errore di Chrome che vorrei capire. ho cercato il web in modo veloce ma non ho trovato una spiegazione, quindi credo che potrei fare qualcosa di terribilmente sbagliato.Come impedire net :: ERR_INCOMPLETE_CHUNKED_ENCODING quando si utilizzano eventi server HTML5 e servlet Java?

Sul lato server Ho una semplice servlet che accetta le richieste e crea un manichino compito Creatore evento:

private Executor executor = Executors.newSingleThreadExecutor(); 

public void doGet(final HttpServletRequest request, final HttpServletResponse response) 
{ 
    final AsyncContext asynCtx = request.startAsync(request, response); 

    response.setHeader("Cache-Control", "no-cache"); 
    response.setContentType("text/event-stream"); 
    response.setCharacterEncoding("utf-8"); 

    executor.execute(() -> { 
    boolean run = true; 
    try 
    { 
     while (run) 
     { 
     final ServletResponse resp = asynCtx.getResponse(); 
     run = resp != null; 

     if (resp != null) 
     { 
      System.out.println("pushing a server event."); 
      final PrintWriter writer = asynCtx.getResponse().getWriter(); 
      writer.println("data: {time: " + System.currentTimeMillis() + "}\n"); 
      writer.flush(); 
     } 
     else 
     { 
      System.out.println("stopping beeper, no response object available anymore."); 
      break; // do not run anymore, we got no response 
     } 

     Thread.sleep(2000); 
     } 
    } 
    catch (final Exception e) 
    { 
     e.printStackTrace(); 
    } 
    }); 

} 

sul client ho semplicemente:

$(document).ready(function() 
{ 

    var source = new EventSource("/events"); 
    source.onmessage = function (event) 
    { 
    console.log("received event: " + JSON.stringify(event)); 
    document.getElementById("eventContainer").innerHTML += event.data + "<br/>"; 
    }; 

    console.log("start to receive events...") 
}); 

quando ho caricare il file HTML funziona, gli eventi vengono ricevuti e scritti sulla console. Ma Dopo 30 secondi ottengo un messaggio di errore:

GET [HttpOfLocalhost]/eventi Net :: ERR_INCOMPLETE_CHUNKED_ENCODING

perché?

la richiesta viene uccisa e ne viene avviata una nuova immediatamente in modo da non uccidere l'applicazione ma i messaggi di errore sulla console non sono belli.

screenshot del mio console sviluppatore:

enter image description here

richiesta DETTAGLI/resposne:

enter image description here

tempistica, questo dimostra che si verifica sempre dopo 30 secondi:

enter image description here

Grazie!

risposta

3

Ok, quindi non potevo stare fermo e guardare più da vicino che cosa sta succedendo.

L'oggetto AsyncContext ha un metodo setTimeout(...). Per impostazione predefinita nella mia versione di tomcat (Tomcat embedded 8) il valore è impostato su 30.000 ms (30 secondi). Questa è esattamente la durata dopo che ho ricevuto l'errore net :: ERR_INCOMPLETE_CHUNKED_ENCODING nella mia console di Chrome.

ho controllato utilizzando:

System.out.println("Current Timeout is: " + asynCtx.getTimeout() + " ms"); 

che ha mostrato:

Current Timeout is: 30000 ms 

in modo da evitare la rete: ERR messaggio qualcuno potrebbe impostare il timeout a 0. Ma di thread evento continua a funzionare per sempre (purtroppo). Un'altra soluzione, che ho utilizzato, è aggiungere AsyncListener allo AsyncContext e chiamare il metodo complete() all'interno del metodo onTimeout().

dal doc API del metodo completa():

Completa l'operazione asincrona che è stato avviato sulla richiesta utilizzato per initialze questo AsyncContext, chiudendo la risposta che è stato utilizzato per inizializzare questo AsyncContext. Eventuali ascoltatori di tipo AsyncListener che sono stati registrati con la ServletRequest per il quale è stato creato questo AsyncContext sarà richiamato al loro metodo onComplete .

il codice sorgente del mio ascoltatore:

asynCtx.addListener(new AsyncListener() 
{ 
    @Override 
    public void onComplete(AsyncEvent asyncEvent) throws IOException 
    { 
    System.out.println("onComplete(...)"); 
    } 

    @Override 
    public void onTimeout(AsyncEvent asyncEvent) throws IOException 
    { 
    // this will close the request and the context gracefully 
    // and the net:ERR is gone. 
    asyncEvent.getAsyncContext().complete(); 
    System.out.println("onTimeout(...)"); 
    } 

    @Override 
    public void onError(AsyncEvent asyncEvent) throws IOException 
    { 
    System.out.println("onError(...)"); 
    } 

    @Override 
    public void onStartAsync(AsyncEvent asyncEvent) throws IOException 
    { 
    System.out.println("onStart(...)"); 
    } 
}); 

quindi sì, è stato a causa mancanza di conoscenza. Spero che questo sia utile per qualcuno.

+2

Mi dica per favore. Ho questo errore, ma io non uso Asynk. Ho andare alla pagina e non ho questo errore. – Tsyklop

2

È possibile inviare piccola "nessuna operazione" pezzi (NOOP) per mantenere attiva la connessione ogni 10 secondi o giù di lì.

Problemi correlati