【问题标题】:Server Sent Event unexpected behavior服务器发送事件意外行为
【发布时间】:2020-07-25 23:05:39
【问题描述】:

我正在尝试在我的 Golang 服务器和 VueJS 之间设置一个基本流。我关注了StackOverflow 上的另一个帖子开始。但是,由于某些奇怪的原因,当我在 chrome 中检查控制台时,输出会不断重复(0、1、2、3、4 -short stop- 0、1、2、3、4 -short stop- 等)。

这是我的代码

main.go

  package main

  import (
    "io"
    "time"

    "github.com/gin-contrib/static"
    "github.com/gin-gonic/gin"
  )
  
  func main() {
        r := gin.Default()
        r.GET("/stream", func(c *gin.Context) {
            chanStream := make(chan int, 2)
            go func() {
                defer close(chanStream)
                for i := 0; i < 5; i++ {
                    chanStream <- i
                    time.Sleep(time.Second * 1)
                }
            }()
            c.Stream(func(w io.Writer) bool {
                if msg, ok := <-chanStream; ok {
                    c.SSEvent("message", msg)
                    return true
                }
                return false
            })
        })
        r.StaticFile("/", "./public.html") 
        r.Use(static.Serve("/", static.LocalFile("./public.html", true)))
        r.Run()
  }

public.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
var stream = new EventSource("/stream");
stream.addEventListener("message", function(e){
    console.log(e.data);
});
</script>    
</body>
</html>

我是 SSE 和 Vue 的新手,但我认为客户端等待来自服务器的响应。我的期望是,一旦 Gin 流结束,客户端就会一直等待并且在我执行 EventSource.close() 之前什么都不做。输出似乎服务器正常发送响应,但一旦流结束客户端继续发出请求?我不确定。有人可以指出我做错了什么吗?谢谢

【问题讨论】:

    标签: go server-sent-events go-gin


    【解决方案1】:

    其实你没有错。这是EventSource api 的预期功能,它总是触发调用,除非它明确停止。检查EventSource API

    EventSource 接口是 Web 内容到服务器发送的接口 事件。一个 EventSource 实例打开一个持久连接到一个 HTTP 服务器,以文本/事件流格式发送事件。这 连接保持打开状态,直到通过调用 EventSource.close() 关闭。

    因此,您需要在服务器完成发送数据时进行更新,并让客户端知道流是否已停止。这是您代码中的示例:

    ma​​in.go

            go func() {
                defer close(chanStream)
                for i := 0; i < 5; i++ {
                    chanStream <- i
                    time.Sleep(time.Second * 1)
                }
            }()
            c.Stream(func(w io.Writer) bool {
                if msg, ok := <-chanStream; ok {
                    if msg < 4 {
                        c.SSEvent("message", msg)
                    } else {
                        c.SSEvent("message", "STOPPED")
                    }
                    return true
                }
                return false
            })
    

    public.html

        stream.addEventListener("message", function(e){
            if (e.data === "STOPPED") {
                console.log("STOP");
                stream.close();
            } else {
                console.log(e.data);
            }
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-24
      • 2015-06-16
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      • 2020-06-20
      • 2013-05-01
      • 2021-01-01
      相关资源
      最近更新 更多