Wie funktioniert Server-Sent-Events arbeiten
Habe ich versucht eine SSE (Server-Sent-Events) mithilfe von java auf tomcat 8.0. Hier sind einige Dinge, die ich bemerkt.
Ich auf eine Schaltfläche klicken, können Sie automatisch eine Anfrage an das servlet. Servlet GET-Methode wird ausgeführt, das gibt ein event-stream. Sobald der stream empfangen wird, wird die Seite erneut automatisch eine weitere Anforderung, die erhält die gleichen Daten wieder!!!!! Ich glaube nicht, haben eine unendliche Schleife, die es gibt!!!
- Was ist eigentlich Los auf dem server? In normalen Szenarien, tomcat erstellt einen thread, behandeln jede Anfrage. Was ist jetzt passiert?
- Was ist der richtige Weg, um sicherzustellen, dass die event-stream nur einmal geschickt wird, um die gleiche Verbindung/browser-Sitzung?
- Was ist der richtige Weg, um sicherzustellen, dass der Fall abgeschlossen ist und keine Ressource overhead verursacht auf dem server?
- Wie die Unterscheidung zwischen GET-und POST-Anfragen. Warum hat man es sich aussuchen?
- Ist es zu früh, um zu verwenden, SSE auf Tomcat? Irgendwelche performance Probleme?
Hier ist der code für die neugierigen,
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//content type must be set to text/event-stream
response.setContentType("text/event-stream");
//cache must be set to no-cache
response.setHeader("Cache-Control", "no-cache");
//encoding is set to UTF-8
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
for(int i=0; i<10; i++) {
System.out.println(i);
writer.write("data: "+ i +"\n\n");
writer.flush();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
writer.close();
}
}
Javascript auf der Seite (ich habe nichts anderes auf der Seite),
<button onclick="start()">Start</button>
<script type="text/javascript">
function start() {
var eventSource = new EventSource("TestServlet");
eventSource.onmessage = function(event) {
console.log("data: "+event.data)
document.getElementById('foo').innerHTML = event.data;
};
}
</script>
Versucht, diese mithilfe von CURL. Und die Antwort kam nur einmal. Ich bin mit chrome, also das muss ein Problem mit chorme??
EDIT:
Was ich gelernt habe und lernen ist nun dokumentiert in meinem blog - Server Gesendeten Ereignisse
Ja, du hast Recht. LOCKE hielt mit einer Anfrage.
Ich habe mich für das gleiche ein... zumindest war ich in der Lage, sparen Sie sich die Zeit & frustration 😉
Ich glaube nicht, dass Ihr problem mit dem browser. Ich bin mit solchem denken vom letzten 6-8 Monaten und es funktioniert gut auf die Produktion. Überprüfen Sie mit Ihrem Skript kann von start() wird immer aufgerufen, mehrere Male?
Aber wie ist das möglich? Ich kommentierte den code, und legen Sie eine Konsole.log-und es wird immer aufgerufen, nur einmal wenn ich auf die Schaltfläche klicke. Wenn Sie wurden mit dieser für Monate, dann haben Sie vielleicht Antworten auf meine Frage.
InformationsquelleAutor John | 2015-08-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ändern Sie diese Zeile
zu
BTW, dein code wird eine ernsthafte performance-Problem, weil es wird halt ein thread, bis alle Ereignisse gesendet werden.Verwenden Sie bitte die Asynchrone Verarbeitung-API statt. z.B.
Dann können wir AsyncContext später
wenn alle gesendeten Ereignisse können wir schließen
UPDATE 1:
Wir brauchen, schließen Sie die Quelle im browser, wenn wir nicht möchten, dass browser, verbinden Sie den server erneut, wenn der server vervollständigt die Reaktion.
Andere Methode, die vielleicht hilft, viz. wir legen einen sehr großen Zeit wiederholt, aber ich habe es nicht ausprobiert, z.B.
UPDATE 2:
Ich denke Websocket ist vielleicht besser für Ihren Fall.
UPDATE 3: (beantworten Sie die Fragen)
Wenn die Nutzung NIO-Stecker, der standardmäßig im Tomcat 8.0.X, die innerhalb des gesamten verarbeitungszyklus HTTP-I/O über eine Anfrage wird nicht halten, ein thread. Wenn Biodiesel zu einem thread zu halten, bis die gesamte Verarbeitung Zyklus abgeschlossen ist. Alle threads werden von einem thread-pool, tomcat nicht schaffen, einen thread für jede Anforderung.
Tun
eventSource.close()
auf browser-Seite die beste Wahl.Vergessen Sie nicht aufrufen AsyncContext.vollständige() auf server-Seite.
Die EventSource-API in einem browser nur GET-Anforderungen unterstützt, aber auf der server-Seite gibt 's diese Beschränkung nicht.
SSE wird hauptsächlich verwendet, um Ereignisse empfangen von Daten vom server. Wenn ein Ereignis passiert, die browser können es in der Zeit und keine Notwendigkeit, erstellen Sie eine neue Anfrage zu Umfrage.
Wenn Sie brauchen, full-duplex-Kommunikation versuchen WebSocket instread von SSE.
Sollte es keine performance-Probleme, wenn wir die NIO-connector & Asynchronous processing API. Ich weiß nicht, ob Tomcat NIO-connector ist reif oder nicht, aber etwas wird nie bekannt werden, es sei denn, wir versuchen es.
Schließen ist besser. Über GET-oder POST-es gibt keine Beschränkung auf server-Seite.Aber nach dem [W3C-SPEC](w3.org/TR/eventsource ), browser wird immer mit GET statt POST, und es 's keine option zum aktivieren von POST.
Nun, das ist eine Antwort. Danke.
writer.write("data: "+ i +"\n\n");
funktioniert.Nach der spec: "Clients verbinden, wenn die Verbindung geschlossen ist; ein client kann gesagt werden, zu beenden wiederherstellen der Verbindung mit dem HTTP-Statuscode 204 No Content-response-code ein." Ich habe mit Java impl der SSE durch mein selbst, können Sie es hier: github.com/metteo/event-source
InformationsquelleAutor xfeep
Ich empfehle zuerst zu Lesen Stream-Updates mit Server-Sent Events, um ein gutes Verständnis von der Technik.
Dann Folgen Server-Sent Events mit Async Servlet Beispiel Durch zu sehen, wie SSE verwendet werden kann, die speziell mit der Servlet-Technologie.
Sieht aus wie etwas geändert wurde in der zugrunde liegenden blog-engine, die Auswirkungen auf die code-Formatierung -- es war nicht so vor (:
Zweiter link ist kaputt, fand es in der waybackmachine: web.archive.org/web/20150910123522/https://weblogs.java.net/...
InformationsquelleAutor 01es