服务器发送事件意外行为
Server Sent Event unexpected behavior
我正在尝试在我的 Golang 服务器和 VueJS 之间设置一个基本流。我在 Whosebug 上关注了另一个 post 开始。但是,由于某些奇怪的原因,当我在 chrome 中检查我的控制台时,输出不断重复(0、1、2、3、4 -short stop- 0、1、2、3、4 -short stop- etc ..).
这是我的代码
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() 之前不做任何事情。输出似乎服务器正常发送响应,但客户端在流结束后继续发出请求?我不确定。有人可以指出我做错了什么吗?谢谢
其实你没有看错。这是 EventSource
api 的预期功能,它总是触发调用,除非它明确停止。检查 EventSource API
The EventSource interface is web content's interface to server-sent
events. An EventSource instance opens a persistent connection to an
HTTP server, which sends events in text/event-stream format. The
connection remains open until closed by calling 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
})
public.html
stream.addEventListener("message", function(e){
if (e.data === "STOPPED") {
console.log("STOP");
stream.close();
} else {
console.log(e.data);
}
});
我正在尝试在我的 Golang 服务器和 VueJS 之间设置一个基本流。我在 Whosebug 上关注了另一个 post 开始。但是,由于某些奇怪的原因,当我在 chrome 中检查我的控制台时,输出不断重复(0、1、2、3、4 -short stop- 0、1、2、3、4 -short stop- etc ..).
这是我的代码
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() 之前不做任何事情。输出似乎服务器正常发送响应,但客户端在流结束后继续发出请求?我不确定。有人可以指出我做错了什么吗?谢谢
其实你没有看错。这是 EventSource
api 的预期功能,它总是触发调用,除非它明确停止。检查 EventSource API
The EventSource interface is web content's interface to server-sent events. An EventSource instance opens a persistent connection to an HTTP server, which sends events in text/event-stream format. The connection remains open until closed by calling 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
})
public.html
stream.addEventListener("message", function(e){
if (e.data === "STOPPED") {
console.log("STOP");
stream.close();
} else {
console.log(e.data);
}
});