time.Sleep 和 Go 中的服务器发送事件 - 意外行为

time.Sleep and server-sent-events in Go - unexpected behavior

我正在尝试学习在 Go 中使用服务器发送的事件 (SSE)。这 以下是我不理解的行为。

我所期望的(和想要实现的):每秒发送一条消息; 这将发生五次,然后连接将关闭。

实际发生了什么:服务器等待大约5秒然后发送 立即发送所有消息,然后关闭连接。

如果你能帮助我理解为什么会这样,我将不胜感激。 我不清楚我的想法哪里出了问题。 每次循环开始时,它应该发送一条消息,休眠然后开始一个新的 迭代。

谢谢。

服务器上的相关代码

func realTimeHandler(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "text/event-stream")
    w.Header().Set("Cache-Control", "no-cache")

    i := 0
    var msg string
    for {
        msg = fmt.Sprintf("data: Message %d\n\n", i)
        i = i + 1
        w.Write([]byte(msg))
        time.Sleep(time.Second)
        if i > 5 {
            break
        }
    }
    w.Write([]byte("data:close\n\n"))
    return
}

客户端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SSE</title>
</head>
<body>
    <div id="realtime"></div>

    <script type="text/javascript">
        var evtsrc = new EventSource("/realTimeEvts");

        evtsrc.onmessage = function(e) {
            console.log("message received");
            if (e.data == "close") {
                console.log("closing connection!");
                evtsrc.close();
            }
            console.log(e.data);
        };

        evtsrc.onerror = function(e) {
            console.log(evtsrc.readyState);
            console.log("error!");
        };
    </script>
</body>
</html>

服务器缓冲响应正文。 Flush 修复此问题的缓冲区:

w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
f, ok := w.(http.Flusher)
if !ok {
    http.Error(w, "sse not supported", 400)
    return
}
for i := 0; i < 5; i++ {
    fmt.Fprintf(w, "data: Message %d\n\n", i)
    f.Flush()
    time.Sleep(time.Second)
}
w.Write([]byte("data:close\n\n"))