- 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.