r3labs / sse

Server Sent Events server and client for Golang
Mozilla Public License 2.0
870 stars 180 forks source link

Streaming unsupported #130

Closed mooijtech closed 2 years ago

mooijtech commented 2 years ago

Hello,

I am trying to setup SSE for a progress bar but I am getting "Streaming unsupported!" in FireFox.

Client:

const source = new EventSource("http://localhost:1337/outlook/loading?stream=" + projectId, {withCredentials: true})
source.onmessage = e => console.log(e.data)

Server:

func (server *Server) Start() {
    server.ServerSentEvents = sse.New()

    server.Router.HandleFunc("/outlook/loading", server.ServerSentEvents.ServeHTTP)
}
go func() {
    server.ServerSentEvents.CreateStream(project.UUID)

    for percentage := range progressPercentageChannel {
        server.ServerSentEvents.Publish(project.UUID, &sse.Event{
            Data: []byte(fmt.Sprintf("%d%", percentage)),
        })
    }
}()
mooijtech commented 2 years ago

It seems like for some reason the http.ResponseWriter has no http.Flusher?

mooijtech commented 2 years ago

As per the documentation:

The default HTTP/1.x and HTTP/2 ResponseWriter implementations
support Flusher, but ResponseWriter wrappers may not.

I am using a CORS wrapper:

corsHandler := cors.New(cors.Options{
    AllowedOrigins:   []string{"http://localhost:3000", "http://127.0.0.1:3000"},
    AllowedMethods:   []string{http.MethodGet, http.MethodPost, http.MethodDelete},
    AllowCredentials: true,
}).Handler(server.Router)

Logger.Fatal(http.ListenAndServe(":1337", server.SessionManager.LoadAndSave(corsHandler)))

Most likely this is the issue.

mooijtech commented 2 years ago

I need CORS otherwise the EventSource request will be blocked by CORS.

mooijtech commented 2 years ago

I'm still getting "Streaming unsupported!" even if I add the CORS header manually and remove the CORS library.

mooijtech commented 2 years ago

Maybe the session manager doesn't support it?

purehyperbole commented 2 years ago

Hey @mooijtech ,

Please could you try and run this simpler example and see if it behaves correctly? I am unable to reproduce the issue you are seeing.

package main

import (
    "time"
    "net/http"

    "github.com/r3labs/sse/v2"
)

func main() {
    s := sse.New()

    s.CreateStream("test")

    go func() {
        for {
            s.Publish("test", &sse.Event{Data: []byte("hello")})    
            time.Sleep(time.Second) 
        }
    }()

    s.Headers = map[string]string{
        "Access-Control-Allow-Origin": "*",
    }

    // Create a new Mux and set the handler
    mux := http.NewServeMux()
    mux.HandleFunc("/", s.ServeHTTP)

    http.ListenAndServe(":8080", mux)       
}
mooijtech commented 2 years ago

Hello,

Thanks for your response. It seems to be an issue with the session manager I'm using. I have removed the server.SessionManager.LoadAndSave function and now it works. It seems the session manager is wrapping http.ResponseWriter and apparently doesn't have the http.Flusher.

I will open an issue there.