r3labs / sse

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

onSubscribe send a message to the subscriber #177

Open Cyliann opened 9 months ago

Cyliann commented 9 months ago

Is it possible to send a message to the subscriber as soon as it subscribes? I need to send an ID to every new client connected. Sadly, this doesn't work:

func main() {
        server := sse.New()
    mux := http.NewServeMux()
    mux.HandleFunc("/events", eventHandler)

    http.ListenAndServe(":8080", mux)
}

func eventHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Message"))
    w.(http.Flusher).Flush()

    server.ServeHTTP(w, r)
}

I though that onSubsrcibe() can to that, but it doesn't allow passing http.ResponseWriter in any way and I can't see how it can be accomplished otherwise. I've been banging my head over the wall for the past 2 days and I can't get it to work. Could you provide any help?

Prasannakumar414 commented 1 week ago

Hello @Cyliann you can add the headers to keep connection alive and connection type to event stream. For SSE connection we must have following things

func main() {
        server := sse.New()
    mux := http.NewServeMux()
    mux.HandleFunc("/events", eventHandler)

    http.ListenAndServe(":8080", mux)
}

func eventHandler(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/event-stream")
    w.Header().Set("Cache-Control", "no-cache")
    w.Header().Set("Connection", "keep-alive")
    w.Write([]byte("Message"))
    w.(http.Flusher).Flush()

    server.ServeHTTP(w, r)
}

I have implemented something like this and it is working for me

mux.HandleFunc("/events", func(w http.ResponseWriter, r *http.Request) {
        go func() {
            <-r.Context().Done()
            done <- true
            println("The client is disconnected here")
        }()
        w.Header().Set("Content-Type", "text/event-stream")
        w.Header().Set("Cache-Control", "no-cache")
        w.Header().Set("Connection", "keep-alive")
        rc := http.NewResponseController(w)
        _, err := fmt.Fprintf(w, "data:congo on entering to sse\n\n")
        if err != nil {
            return
        }
        err = rc.Flush()
        if err != nil {
            return
        }

        server.ServeHTTP(w, r)
    })