Server Sent Events in Golang - Browser get event stream funktioniert nur bei localhost
Servus,
ich möchte "Server Sent Events" mit Golang realisieren. Ich benutze dafür die hier beschriebene Bibliothek: https://thoughtbot.com/blog/writing-a-server-sent-events-server-in-go
Es hat auch funktioniert, aber nur mit localhost. Wenn ich meinen Hostnamen in der Adresszeile meines Browsers eingebe, funktioniert die Übertragung nicht. Es funktioniert auch nicht, wenn ich die Website auf einem anderen Client aufrufe.
Wenn ich ein SSE an den Client sende und die Serveranwendung beende, gehen alle Ereignisse sofort bei der Browseranwendung ein. Wenn ich cURL benutze, funktioniert es:
Woran könnte das liegen? Ich benutze die neueste Golang-Bibliothek
Hier ist mein Javascript-Code:
Und hier ist der Golang-Code, den ich aus der Bibliothek verwende:
Die Bibliothek habe ich auch schon ausprobiert, das gleiche passiert aber auch hier: https://github.com/alexandrevicenzi/go-sse
Dann habe ich versucht, die Verbindung nach jeder Nachricht zu trennen und dem Browser den Befehl zu geben, die Verbindung sofort wiederherzustellen.
Hier sind die zwei Zeilen, die ich im Code hinzugefügt habe:
So funktioniert es, aber das ist nur ein Workaround für mich. Problem ist, das zwischen der Zeit, nach der die Verbindung beendet und wieder eine neue Verbindung aufgebaut wurde, keine Aktualisierung stattfindet. Hat jemand eine bessere Lösung, wie es funktioniert, während die Verbindung bestehen bleibt?
ich möchte "Server Sent Events" mit Golang realisieren. Ich benutze dafür die hier beschriebene Bibliothek: https://thoughtbot.com/blog/writing-a-server-sent-events-server-in-go
Es hat auch funktioniert, aber nur mit localhost. Wenn ich meinen Hostnamen in der Adresszeile meines Browsers eingebe, funktioniert die Übertragung nicht. Es funktioniert auch nicht, wenn ich die Website auf einem anderen Client aufrufe.
Wenn ich ein SSE an den Client sende und die Serveranwendung beende, gehen alle Ereignisse sofort bei der Browseranwendung ein. Wenn ich cURL benutze, funktioniert es:
curl -v myhost:8081/updates
* Trying ....
* TCP_NODELAY set
* Connected to myhost (...) port 8081 (#0)
> GET /updates HTTP/1.1
> Host: myhost:8081
> User-Agent: curl/7.50.3
> Accept: */*
>
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Cache-Control: no-cache
< Connection: keep-alive
< Content-Type: text/event-stream
< Date: Fri, 29 Nov 2019 17:07:27 GMT
< Transfer-Encoding: chunked
<
data: {"X":127,"Y":227,"Zeitpunkt":"29.11.2019 18:07:27"}
data: {"X":128,"Y":228,"Zeitpunkt":"29.11.2019 18:07:28"}
data: {"X":128,"Y":228,"Zeitpunkt":"29.11.2019 18:07:29"}
Woran könnte das liegen? Ich benutze die neueste Golang-Bibliothek
Hier ist mein Javascript-Code:
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("updates");
source.onmessage = function(event) {
var pmstat = jQuery.parseJSON(event.data);
$('#bestandX').html(pmstat.X);
$('#bestandY').html(pmstat.Y);
$('#aktualisiertAm').html(pmstat.Zeitpunkt);
};
} else {
$('body').html('<h1 style="color: red">Browser unterstützt keine Server-sent events.</h1>')
}
</script>
Und hier ist der Golang-Code, den ich aus der Bibliothek verwende:
// Implement the http.Handler interface.
// This allows us to wrap HTTP handlers (see auth_handler.go)
// http://golang.org/pkg/net/http/#Handler
func (broker *Broker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
// Make sure that the writer supports flushing.
//
flusher, ok := rw.(http.Flusher)
if !ok {
http.Error(rw, "Streaming unsupported!", http.StatusInternalServerError)
return
}
// Set the headers related to event streaming.
rw.Header().Set("Content-Type", "text/event-stream")
rw.Header().Set("Cache-Control", "no-cache")
rw.Header().Set("Connection", "keep-alive")
rw.Header().Set("Access-Control-Allow-Origin", "*")
// Each connection registers its own message channel with the Broker's connections registry
messageChan := make(MessageChan)
// Signal the broker that we have a new connection
broker.newClients <- messageChan
// Remove this client from the map of connected clients
// when this handler exits.
defer func() {
fmt.Println("HERE.")
broker.closingClients <- messageChan
}()
// "raw" query string option
// If provided, send raw JSON lines instead of SSE-compliant strings.
req.ParseForm()
raw := len(req.Form["raw"]) > 0
// Listen to connection close and un-register messageChan
notify := rw.(http.CloseNotifier).CloseNotify()
go func() {
<-notify
broker.closingClients <- messageChan
}()
// block waiting or messages broadcast on this connection's messageChan
for {
// Write to the ResponseWriter
if raw {
// Raw JSON events, one per line
fmt.Fprintf(rw, "%s\n", <-messageChan)
} else {
// Server Sent Events compatible
fmt.Fprintf(rw, "data: %s\n\n", <-messageChan)
}
// Flush the data inmediatly instead of buffering it for later.
flusher.Flush()
}
}
Die Bibliothek habe ich auch schon ausprobiert, das gleiche passiert aber auch hier: https://github.com/alexandrevicenzi/go-sse
Dann habe ich versucht, die Verbindung nach jeder Nachricht zu trennen und dem Browser den Befehl zu geben, die Verbindung sofort wiederherzustellen.
Hier sind die zwei Zeilen, die ich im Code hinzugefügt habe:
...
go func() {
<-notify
broker.closingClients <- messageChan
}()
// block waiting or messages broadcast on this connection's messageChan
for {
// Write to the ResponseWriter
if raw {
// Raw JSON events, one per line
fmt.Fprintf(rw, "%s\n", <-messageChan)
} else {
// Server Sent Events compatible
fmt.Fprintf(rw, "retry: %d\n", 0) //<--- I added this
fmt.Fprintf(rw, "data: %s\n\n", <-messageChan)
}
// Flush the data inmediatly instead of buffering it for later.
flusher.Flush()
break //<--- I added this
}
}
So funktioniert es, aber das ist nur ein Workaround für mich. Problem ist, das zwischen der Zeit, nach der die Verbindung beendet und wieder eine neue Verbindung aufgebaut wurde, keine Aktualisierung stattfindet. Hat jemand eine bessere Lösung, wie es funktioniert, während die Verbindung bestehen bleibt?
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 521735
Url: https://administrator.de/forum/server-sent-events-in-golang-browser-get-event-stream-funktioniert-nur-bei-localhost-521735.html
Ausgedruckt am: 26.12.2024 um 17:12 Uhr
1 Kommentar