• With issues:
  • Why can't I receive the ctx.Done() signal in ctx.stream when closing the client connection when using SSE long connection?

Description

When I close the sse long connection, ctx.Done() cannot receive the signal, causing the connection to not be released.

How to reproduce

ctx.Writer.Header().Set("Content-Type", "text/event-stream")
    ctx.Writer.Header().Set("Cache-Control", "no-cache")
    ctx.Writer.Header().Set("Connection", "keep-alive")
    ctx.Writer.Header().Set("Transfer-Encoding", "chunked")
    ctx.Writer.Header().Set("X-Accel-Buffering", "no")
    fmt.Fprintf(ctx.Writer, "data: %s\n\n", "connected")
    ctx.Writer.Flush()
    ctx.Stream(func(w io.Writer) bool {
        select {
        case <-ctx.Request.Context().Done():
            w.Write([]byte("data:[done]\n\n"))
            log.Info("capture result listen done")
            return false
        case cr := <-newChan:
            if cr == nil {
                return false
            }
            data, err := json.Marshal(cr)
            if err != nil {
                log.Errorf("marshal capture result failed, err: %v", err)
                return false
            }
            _, err = fmt.Fprintf(w, "data: %s\n\n", data)
            if err != nil {
                log.Errorf("write capture result failed, err: %v", err)
                return false
            }
            w.(http.Flusher).Flush()
            return true
        }
    })

Expectations

When closing the client connection, print"capture result listen done"

Actual result

After the connection is closed, only failure to send again will trigger the end of the loop.

Environment

  • go version: 1.22.0
  • gin version (or commit ref): 1.9.1
  • operating system: linux

Comment From: Axb12

You can try using notify := c.Writer.CloseNotify().

And replace <-ctx.Request.Context().Done() with <-notify

Comment From: li-zheng-hao

You can try using notify := c.Writer.CloseNotify().

And replace <-ctx.Request.Context().Done() with <-notify

It still doesn't work. I tried to run this sample: https://gist.github.com/SubCoder1/3a700149b2e7bb179a9123c6283030ff and replaced <-ctx.Request.Context().Done() with notify := c.Writer.CloseNotify()

After I refresh the Chrome tab or close the Chrome window, the notify channel never receives any signal.

Image