为了账号安全,请及时绑定邮箱和手机立即绑定

服务器发送事件意外行为

服务器发送事件意外行为

Go
慕田峪7331174 2022-06-21 10:01:35
我正在尝试在我的 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() 之前什么都不做。输出似乎服务器正常发送响应,但一旦流结束客户端继续发出请求?我不确定。有人可以指出我做错了什么吗?谢谢
查看完整描述

1 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

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


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


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


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

        })

公共.html


    stream.addEventListener("message", function(e){

        if (e.data === "STOPPED") {

            console.log("STOP");

            stream.close();

        } else {

            console.log(e.data);

        }

    });


查看完整回答
反对 回复 2022-06-21
  • 1 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号