2016-05-24 19 views
2

Ich versuche Server Sent Events mit Spring SseEmitter wie in dieser Youtube video beschrieben zu implementieren.HTML5 EventSource sendet mehrere Anfragen

Ich bin in der Lage, den Ereignisstrom zu initiieren und die Daten vom Server gesendet Ereignis zu empfangen.

Allerdings kann ich mehrere EventStream Typ Anfragen vom Client ausgelöst und auf dem Server ankommen. Die Art, wie ich es verstehe, EventSource sollte eine einzige HTTP Anfrage senden und sollte dann eine half duplex Verbindung vom Server erhalten, mit dem Server die Ereignisse an den Client sendet.

Warum sendet es dann Anfragen in regelmäßigen Abständen? Ist das nicht wie ein Polling anstelle einer Halbduplex-Verbindung?

Bellow ist der Code, den ich verwende.

Server Code

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.RestController; 
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; 
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter.SseEventBuilder; 

@RestController 
public class TestService { 
    private List<SseEmitter> subscriberList = Collections.synchronizedList(new ArrayList<>()); 

    @RequestMapping("inbox") 
    public SseEmitter inbox() { 
     SseEmitter subscriber = new SseEmitter(); 
     subscriberList.add(subscriber); 

     subscriber.onCompletion(() -> { 
      subscriberList.remove(subscriber); 
      System.out.println("Removed the completed event emitter"); 
     }); 

     System.out.println("Subscriber arrived"); 
     return subscriber; 
    } 

    @RequestMapping("message") 
    public String message(@RequestParam("message") String message) { 
     System.out.println("SubscriberList size " + subscriberList.size()); 
     for(SseEmitter subscriber : subscriberList) { 
      try { 
       SseEventBuilder eventBuilder = SseEmitter.event().name("group1").data(message); 
       subscriber.send(eventBuilder); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     }; 
     return message; 
    } 
} 

Client-Code

$(function() { 
    console.log("Started"); 
    var eventSource = new EventSource("/inbox"); 
    eventSource.addEventListener('error', function(e) { 
     if (e.currentTarget.readyState == EventSource.CLOSED) { 
      console.log("Connection is closed") 
     } else { 
     source.close(); 
     console.log("Closing connection"); 
     } 
    }); 
    eventSource.addEventListener("group1", function (event) { 
     console.log(event.data); 
     document.querySelector("body").innerHTML += "<div>" + event.data + "</div>"; 
    }); 
}); 

Bellow ist die Client-Netzwerk-Registerkarte Screenshot aus Chrom

enter image description here

Hier Serverseite log

Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 
Removed the completed event emitter 
Subscriber arrived 

Antwort

2

Das Problem hierbei ist, dass der Server die Verbindung unerwartet geschlossen wird, anstatt ihre Arbeit zu tun, während sie offen zu lassen. Wenn dies der Fall ist, sendet der Client erneut eine Anforderung zum Öffnen einer Verbindung und zum Starten des Streams von Server-gesendeten Ereignissen. Der Server schließt die Verbindung dann immer wieder und führt zu einer Infinate-Schleife.

Eine Möglichkeit, um sicherzustellen, dass dies der Fall ist, ist das Feld retry, um die Wartezeit des Browsers zu erhöhen (die Standardeinstellung beträgt etwa 2-3 Sekunden). Ein anderer Weg ist, eine while (true) {} auf der Serverseite zu haben, gleich nachdem die Anfrage eintrifft.

Werfen Sie einen Blick auf this post über SSEs.

+0

Danke, ich werde versuchen, das Netzwerk für geschlossene Sockets zu überwachen und meine Erkenntnisse zu teilen. – 11thdimension