2014-11-11 4 views
8

Ich habe gerade angefangen, mit Server-Events herumzuspielen, und ich laufe auf eine Chrom-Fehlermeldung, die ich gerne verstehen würde. Ich habe das Web schnell durchsucht, aber keine Erklärung gefunden, also kann ich etwas sehr falsch machen.Wie verhindert man net :: ERR_INCOMPLETE_CHUNKED_ENCODING bei der Verwendung von HTML5 Server-Ereignissen und Java-Servlets?

Auf der Serverseite i ein einfaches Servlet haben, die Anfragen und erstellt eine Dummy-Ereignis Schöpfer Aufgabe übernimmt:

$(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...") 
}); 

, wenn ich die Datei HTML laden: i einfach

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

} 

auf dem Client Es funktioniert gut, Ereignisse werden empfangen und auf die Konsole geschrieben. Aber nach 30 Sekunden Ich erhalte eine Fehlermeldung:

GET [HttpOfLocalhost]/events net :: ERR_INCOMPLETE_CHUNKED_ENCODING

warum?

Die Anforderung als wird getötet und eine neue wird sofort gestartet, damit es die Anwendung nicht beendet, aber Fehlermeldungen auf der Konsole sind nicht nett.

Screenshot von meinem Entwickler-Konsole:

enter image description here

Anfrage/resposne Details:

enter image description here

Timing, das zeigt, dass es immer nach 30 Sekunden auftritt:

enter image description here

Danke!

Antwort

3

Ok, also konnte ich nicht still stehen und genauer hinsehen was passiert.

Das Objekt AsyncContext verfügt über eine setTimeout(...) Methode. Standardmäßig ist in meiner Tomcat-Version (Tomcat Embedded 8) der Wert auf 30.000 ms (30 Sekunden) eingestellt. Das ist genau die Dauer, nachdem ich den net :: ERR_INCOMPLETE_CHUNKED_ENCODING Fehler in meiner Chrome-Konsole bekommen habe.

i mit geprüft:

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

die zeigte:

Current Timeout is: 30000 ms 

so das Netz zu vermeiden: ERR Nachricht jemand das Timeout auf 0 Aber als der Ereignis-Thread für immer läuft weiter einstellen könnte (Unglücklicherweise). Eine andere Lösung, die ich verwendete, ist eine AsyncListener zu AsyncContext hinzufügen und rufen Sie die complete() Methode innerhalb der onTimeout() Methode.

vom API doc der complete() Methode:

Vervollständigt den asynchronen Betrieb, der auf der Anforderung gestartet wurde die verwendet wurde, um dieses AsyncContext zu initialze, wobei die Antwort Schließen, der verwendet wurde, dies zu initialisieren, AsynchronerKontext. Listener vom Typ AsyncListener, die mit dem ServletRequest registriert wurden, für die diese AsyncContext erstellt wurde, wird an ihrer onComplete Methode aufgerufen werden.

der Quellcode meiner Zuhörer:

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(...)"); 
    } 
}); 

so ja, es war wegen Mangel an Wissen. Ich hoffe, dass das für jemanden hilfreich ist.

+2

Sagen Sie mir bitte. Ich habe diesen Fehler, aber ich weiß nicht Asynk verwenden. Ich gehe auf die Seite und ich habe diesen Fehler. – Tsyklop

2

Sie können kleine „keine Operation“ (noop) Chunks senden, um die Verbindung aufrecht zu erhalten alle 10 Sekunden zu halten oder so.

Verwandte Themen