dongliao1860 2016-07-02 16:46
浏览 59
已采纳

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

I am trying to learn to use server sent events (SSE) with Go. The following is the behavior that I do not understand.

What I expect (and want to implement): one message will be sent after every second; this will happen five times, and then the connection will be closed.

What actually happens: the server waits for about 5 seconds and then sends all messages at once and then the connection is closed.

Would appreciate if you can help me understand why this is happening. It is not clear to me where I am going wrong with how I am thinking about this. Every time the loop starts, it should send a message, sleep and then start a new iteration.

Thank you.

Relevant code on server

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

", i)
        i = i + 1
        w.Write([]byte(msg))
        time.Sleep(time.Second)
        if i > 5 {
            break
        }
    }
    w.Write([]byte("data:close

"))
    return
}

Code on client

<!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>
  • 写回答

1条回答 默认 最新

  • dsqe46004 2016-07-02 17:05
    关注

    The server buffers the response body. Flush the buffer to fix this issue:

    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
    
    ", i)
        f.Flush()
        time.Sleep(time.Second)
    }
    w.Write([]byte("data:close
    
    "))
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 Ubuntu20.04无法连接GitHub
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥30 C++行情软件的tick数据如何高效的合成K线