服务器发送事件意外行为

我正在尝试在我的 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()

  }

公共.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() 之前什么都不做。输出似乎服务器正常发送响应,但一旦流结束客户端继续发出请求?我不确定。有人可以指出我做错了什么吗?谢谢


慕田峪7331174
浏览 129回答 1
1回答

暮色呼如

你没有错,其实。这是 api 的预期功能EventSource,它总是触发调用,除非它明确停止。检查事件源 APIEventSource 接口是 Web 内容与服务器发送事件的接口。EventSource 实例打开与 HTTP 服务器的持久连接,该服务器以文本/事件流格式发送事件。连接保持打开状态,直到通过调用 EventSource.close() 关闭。因此,您需要在服务器完成发送数据时进行更新,并让客户端知道流是否已停止。这是您的代码中的示例:main.go&nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer close(chanStream)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < 5; i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; chanStream <- i&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(time.Second * 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }()&nbsp; &nbsp; &nbsp; &nbsp; c.Stream(func(w io.Writer) bool {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if msg, ok := <-chanStream; ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if msg < 4 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.SSEvent("message", msg)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.SSEvent("message", "STOPPED")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false&nbsp; &nbsp; &nbsp; &nbsp; })公共.html&nbsp; &nbsp; stream.addEventListener("message", function(e){&nbsp; &nbsp; &nbsp; &nbsp; if (e.data === "STOPPED") {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log("STOP");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stream.close();&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(e.data);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; });
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go